Применить ключевой путь в map() в простейшей форме

#swift #swift5 #swift-keypath

#swift #swift5 #swift-ключевой путь

Вопрос:

 let test = [4, 5, 3, 1, 3]
print(
    test.map { $0 }
)
print(
    test.map(.self)  // Doesn't compile  
)
  

Ошибка:

Тип выражения неоднозначен без дополнительного контекста

Почему это не работает? Похоже, что так и должно быть.
Если это не так, как еще мы можем избавиться от уродливого { $ 0 } здесь?

Может быть, пример с compactMap сделает больше смысла))

 let test = [4, 5, nil, 3, 1, nil, 3]
print(
    test.compactMap { $0 }
)
print(
    test.compactMap(.self)  // Doesn't compile  
)
  

Ошибка:

Не удается преобразовать значение типа ‘WRITABLEYPATH<_, _>’ в ожидаемый тип аргумента ‘(Int?) throws -> ElementOfResult?’

Комментарии:

1. Как насчет написания собственной identity функции?

2. @Sweeper Это интересная идея ))) Но почему здесь не работает ключевой путь?

3. Судя по тому, как сформулированы документы , кажется, что .self это несколько особый случай, и он обрабатывается по-другому. У него даже есть свое собственное имя «путь идентификационного ключа».

4. Для меня это похоже на ошибку. Согласно SE-0249 выражения ключевого пути как функции (которые реализованы в Swift 5.2) должны let filtered = [1, nil, 3, nil, 5].compactMap(.self) компилироваться. Но это не так (протестировано в бета-версиях Xcode 11 и 12).

5. Это ошибка : bugs.swift.org/browse/SR-12897

Ответ №1:

Почему это не работает? Похоже, что так и должно быть.

Вы правы. Оба ваших примера должны быть скомпилированы, потому что

Фактически, в последнем предложении явно упоминается пример, похожий на ваш. Однако это не компилируется (начиная с бета-версий Xcode 11.7 и Xcode 12):

 [1, nil, 3, nil, 5].compactMap(.self)
// error: generic parameter 'ElementOfResult' could not be inferred
  

Это ошибка. Об этом уже сообщалось как

В отчете об ошибке упоминается пользовательское расширение в качестве возможного обходного пути:

 extension Optional { var mySelf: Self { self } }

[1, nil, 3, nil, 5].compactMap(.mySelf)