TL; DR
Почему это не работает?Использование init() на карте()
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
Детали
Один действительно здорово, что я люблю в Swift является возможность преобразовать коллекцию одной вещи к другой, передавая в метод инициализации (предполагая init()
для этого типа существует).
Вот пример преобразования списка кортежей в экземпляры ClosedInterval
.
[(1,3), (3,4), (4,5)].map(ClosedInterval.init)
Этот пример также использует тот факт, что мы можем передать кортеж аргументов в качестве единственного аргумента, пока кортеж соответствует список аргументов функции.
Вот еще один пример, на этот раз преобразование списка чисел в строковые экземпляры.
(1...100).map(String.init)
К сожалению, следующий пример не работает. Здесь я пытаюсь разделить строку на список односимвольных строк.
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
map()
должен работать в списке Character
(и на самом деле я был в состоянии проверить на детской площадке, что Swift выводит правильный тип [Характер] здесь, передаваемой в map
).
String
определенно может быть создан из Character
.
let a: Character = "a"
String(a) // this works
И, что интересно, это работает, если персонажи находятся в своем собственном массиве.
"abcdefg".characters.map { [$0] }.map(String.init)
Или эквивалент:
let cx2: [[Character]] = [["a"], ["b"], ["c"], ["d"]]
cx2.map(String.init)
Я знаю, что я мог бы сделать это:
"abcdefg".characters.map { String($0) }
Но я определенно пытаюсь понять, почему "abcdefg".characters.map(String.init)
не работает (IMO этот синтаксис также более читабельны и изящны)
Это отличный ответ. Есть ли ссылочный документ (или даже статья), описывающий использование '.init' таким образом (например, в map/flatMap и т. Д.)? –
Вы можете устранить два инициализатора; используйте 'String.init (_ :)' для обозначения первого. – Sweeper