#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:
Почему это не работает? Похоже, что так и должно быть.
Вы правы. Оба ваших примера должны быть скомпилированы, потому что
- Ключевой путь идентификации SE-0227 был реализован в Swift 5, и
- Выражения ключевого пути SE-0249 как функции были реализованы в Swift 5.2.
Фактически, в последнем предложении явно упоминается пример, похожий на ваш. Однако это не компилируется (начиная с бета-версий 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)