TL; DR
Perché questo non funziona?Utilizzo di init() nella mappa()
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
dettagli
Una cosa davvero cool che mi piace a Swift è la capacità di convertire una raccolta di una cosa all'altra passando in un metodo init (assumendo una init()
per esiste quel tipo).
Ecco un esempio di conversione di un elenco di tuple in istanze di ClosedInterval
.
[(1,3), (3,4), (4,5)].map(ClosedInterval.init)
Che esempio si avvale anche del fatto che siamo in grado di passare una tupla di argomenti come un unico argomento fino a quando il tuple corrisponde lista degli argomenti della funzione.
Ecco un altro esempio, questa volta per convertire un elenco di numeri in istanze di stringa.
(1...100).map(String.init)
Sfortunatamente, il prossimo esempio non funziona. Qui sto cercando di dividere una stringa in una lista di stringhe a singolo carattere.
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
map()
deve funzionare su un elenco di Character
(e in effetti sono stato in grado di verificare in un parco giochi che Swift inferisce il tipo corretto di [carattere] qui di essere passati in map
).
String
definitivamente può essere istanziato da un Character
.
let a: Character = "a"
String(a) // this works
E, cosa interessante, funziona se i caratteri sono ciascuno nel proprio array.
"abcdefg".characters.map { [$0] }.map(String.init)
O l'equivalente:
let cx2: [[Character]] = [["a"], ["b"], ["c"], ["d"]]
cx2.map(String.init)
So che avrei potuto fare questo:
"abcdefg".characters.map { String($0) }
Ma io sono specificamente cercando di capire perché "abcdefg".characters.map(String.init)
non funziona (IMO questa sintassi è anche più leggibile ed elegante)
Questa è una risposta eccellente. C'è un documento di riferimento (o anche un articolo) che descrive l'uso di '.init' in questo modo (ad esempio in map/flatMap, ecc.)? –
È possibile disambiguare i due inizializzatori; usa 'String.init (_ :)' per riferirsi al primo. – Sweeper