Я работаю с Lazy Sequence of Ints:
let a = [1,2,3].lazy
Я начинаю с определения потока Ints следующим образом:
protocol Stream: LazySequenceProtocol where Element == Int {}
extension LazySequence: Stream where Element == Int {}
extension LazyMapSequence: Stream where Element == Int {}
Я буду делать сложные вещи с потоки, но чтобы продемонстрировать проблему, я буду держать вещи простыми. Я расширяю поток, чтобы разрешить увеличивающиеся значения:
extension Stream {
func increment() -> some Stream {
map{ value in
return value + 1
}
}
}
print(Array(a.increment())) // Prints [2, 3, 4]
Обратите внимание, что a.increment () - это ленивая функция, поэтому ее необходимо заключить в Array (), чтобы превратить результаты в массив для печати. .
Также обратите внимание на использование слова "some", которое было введено в Swift 5.1 для представления непрозрачного типа и позволяет нам реализовывать потоки таким образом - без непрозрачных типов это не так. так просто.
И я могу сделать более интересные вещи, такие как вставка 10-кратного значения после себя:
extension Stream {
func insert10x() -> some Stream {
flatMap{ value in
return [value, value*10]
}
}
}
print(Array(a.insert10x())) // Prints [1, 10, 2, 20, 3, 30]
И это означает, что я могу начать составлять свои функции в разных способы:
print(Array(a.insert10x().increment())) // Prints [2, 11, 3, 21, 4, 31]
print(Array(a.increment().insert10x())) // Prints [2, 20, 3, 30, 4, 40]
Все вышеперечисленное компилируется и работает как положено.
НО ... Если я введу дополнительную строку, такую как "let multiplier = 10" ниже, то получу компилятор ошибки:
extension Stream {
func insert10xVersion2() -> some Stream {
flatMap{ value in // Error 1
let multiplier = 10
return [value, value * multiplier] // Error 2
}
}
}
print(Array(a.insert10xVersion2())) // Should prints [1, 10, 2, 20, 3, 30]
Две ошибки компилятора:
Ошибка 1: «flatMap» устарела: пожалуйста, используйте compactMap (_ :) для случая, когда Закрытие возвращает необязательное значение. Вместо этого используйте 'compactMap (_ :).
Ошибка 2: Невозможно преобразовать возвращаемое выражение типа' [Int] 'в тип возвращаемого значения' Int? '
Кажется, что обе ошибки указывают на то, что компилятор решил, что flatMap имеет дело с дополнительными функциями, поэтому поощряет использование взамен CompactMap.
Но я бы подумал, что это должно дать идентичные результаты для первого версия!
Возможно, это ошибка компилятора, но я подумал, что сначала я проверю здесь, чтобы узнать, может ли кто-нибудь увидеть проблему с моим кодом?