Swift offre molte funzionalità nella sua libreria standard, ma puoi accedere a molte funzionalità aggiuntive importando librerie e framework esterni. Questi moduli possono arrivare direttamente dal progetto Swift (come Swift Argument Parser), dai framework delle piattaforme Apple (come Foundation e il Network Framework) oppure da librerie open source di terze parti (come SwiftyBeaver).
I moduli principali, come Foundation, una delle librerie più usate in Swift, sono inclusi nella toolchain di Swift. Le librerie di terze parti devono invece essere aggiunte alla configurazione del progetto (per esempio, usando Swift Package Manager) prima di poterle importare.
Per importare un modulo si scrive la parola chiave import seguita dal nome del modulo.
Quindi puoi importare Foundation aggiungendo le righe seguenti al programma.
import Foundation
Importare un modulo rende disponibili al codice i tipi, i metodi e le funzioni che contiene.
Per esempio, importare Foundation estende String con utili metodi di utilità come components(separatedBy:).
Per convenzione, le istruzioni import si mettono all'inizio di un file Swift, così le dipendenze sono subito visibili a chi legge il codice.
Ai singoli caratteri di una String si accede con lo stesso metodo di indicizzazione usato per gli array.
Tuttavia, gli indici usati per le stringhe non sono numeri interi e non si possono usare direttamente.
Vanno invece calcolati a partire da un altro indice noto, come startIndex, che punta alla posizione del primo carattere di una stringa non vuota, usando i metodi disponibili nelle librerie String e NSString (quando il modulo Foundation è importato, le stringhe in Swift hanno accesso a tutte le proprietà e i metodi di NSString).
Per esempio, data la seguente stringa:
let csv = "apple,pear,peach,orange,cherry,lime,goosberry"
Non si può scrivere csv[21] per ottenere la «g» di «orange»: bisogna invece calcolare un valore di tipo String.Index e usare quell'indice.
Nota che questi indici non sono pensati per essere letti direttamente da una persona.
Sono quelli che si chiamano indici opachi, perché non è necessario sapere cosa contengono.
let index = csv.index(csv.startIndex, offsetBy: 21)
csv[index]
// "g"
print(index)
// prints Index(_rawBits: 1376513)
Nota però che se l'offset non è un indice valido, cioè se restituirebbe un indice prima di startIndex o dopo endIndex, l'operazione genera un errore e fa andare in crash il programma.
Per evitare questo problema, si può specificare un indice limite.
In questo caso si ottiene un indice opzionale, che vale nil per gli indici altrimenti non validi.
let tooFar = csv.index(csv.startIndex, offsetBy: 200)
// error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
let tooFarButSafe = csv.index(csv.startIndex, offsetBy: 200, limitedBy: csv.endIndex)
// nil
Inoltre, gli indici non si possono condividere tra stringhe diverse.
Per esempio, se usi l'index della «g» di «orange» calcolato sopra per indicizzare la stringa fam = "This is my family: 👨👩👦👦, this is our dog: 🐶, this is our cat: 🐱!", cioè fam[index], il programma andrà in crash.
Ci sono molte ragioni dietro tutto questo, ma in sostanza si riducono tutte a una: «Unicode è complicato».
In generale, se ti serve un accesso casuale ai singoli caratteri, probabilmente ti conviene usare un'altra struttura dati, come Array<Character>.
Swift ha i metodi first e last per ottenere il primo e l'ultimo carattere di una stringa.
Questi metodi restituiscono un carattere opzionale, quindi se la stringa è vuota restituiscono nil.
let str = "Hello, world!"
print(str.first) // Prints Optional("H")
print(str.last) // Prints Optional("!")
Puoi anche usare i metodi prefix e suffix per ottenere una sottostringa di una stringa.
Questi metodi accettano un numero intero come argomento e restituiscono una sottostringa con i primi o gli ultimi n caratteri della stringa.
let str = "Hello, world!"
print(str.prefix(5)) // Prints "Hello"
print(str.suffix(6)) // Prints "world!"
Lavorare con il testo è un compito comune nella programmazione. Swift, insieme al framework Foundation, offre molti metodi e proprietà comodi per esaminare, trasformare e manipolare le stringhe.
components(separatedBy:)
Per dividere una stringa in un array di sottostringhe in base a un delimitatore, usa components(separatedBy:) (richiede di importare Foundation):
import Foundation
let sentence = "Hello, world!"
let words = sentence.components(separatedBy: " ")
print(words) // Prints ["Hello,", "world!"]
hasPrefix(_:) e hasSuffix(_:)
Per controllare se una stringa inizia o finisce con una determinata sequenza di caratteri, usa hasPrefix(_:) e hasSuffix(_:):
let greeting = "Hello, world!"
print(greeting.hasPrefix("Hello")) // Prints true
print(greeting.hasSuffix("world!")) // Prints true
Puoi trasformare maiuscole e minuscole di una stringa con questi metodi e proprietà standard:
lowercased(): restituisce una copia della stringa in minuscolo.uppercased(): restituisce una copia della stringa in maiuscolo.capitalized: restituisce una copia in cui la prima lettera di ogni parola è maiuscola (da Foundation).let greeting = "hello, world!"
print(greeting.lowercased()) // Prints "hello, world!"
print(greeting.uppercased()) // Prints "HELLO, WORLD!"
print(greeting.capitalized) // Prints "Hello, World!"
replacingOccurrences(of:with:)
Per sostituire tutte le occorrenze di una sottostringa con un'altra stringa, usa replacingOccurrences(of:with:) (da Foundation):
let greeting = "Hello, world!"
let updated = greeting.replacingOccurrences(of: "world", with: "Swift")
print(updated) // Prints "Hello, Swift!"
joined(separator:)
Il metodo joined(separator:) appartiene alle collezioni di stringhe, come [String].
Unisce gli elementi in un'unica stringa usando un separatore:
let words = ["Hello", "world"]
let sentence = words.joined(separator: ", ")
print(sentence) // Prints "Hello, world"
Un nuovo club di poesia ha aperto in città e stai pensando di andarci. Dato che in passato ci sono stati degli incidenti, il club ha una politica d'ingresso molto particolare che dovrai padroneggiare bene prima di provare a entrare.
Ci sono due porte nel club di poesia, entrambe sorvegliate. Per entrare, dovrai capire qual è la password del giorno:
La prima cosa da fare è dividere la poesia in singole righe. La guardia reciterà una poesia e tu dovrai dividerla in righe.
Implementa la funzione splitOnNewlines che prende una stringa e la divide in un array di stringhe, usando il carattere di nuova riga come delimitatore.
La funzione deve restituire un array di stringhe, dove ogni stringa è una riga della poesia.
splitOnNewlines("Hello.\nHow are you?\n\nI'm doing fine.")
// returns ["Hello." ,"How are you?", "", "I'm doing fine"].
_ al suo posto.Ad esempio, uno dei loro scrittori preferiti è Michael Lockwood, che ha scritto la seguente poesia acrostica: la prima lettera di ogni frase forma una parola.
Stands so high
Huge hooves too
Impatiently waits for
Reins and harness
Eager to leave
Quando la guardia recita la poesia, la dividerai in singole righe e risponderai con le prime lettere di ogni riga, cioè ["S", "H", "I", "R", "E"].
La guardia ti darà poi la parola formata dall'array di lettere con cui hai risposto, così che tu la converta in una parola con l'iniziale maiuscola.
Alla fine la password che restituirai è "SHIRE" ed entrerai.
Implementa la funzione frontDoorPassword che prende una stringa che rappresenta la poesia.
La funzione deve restituire la password che daresti alla guardia.
frontDoorPassword("Stands so high\nHuge hooves too\nImpatiently waits for\nReins and harness\nEager to leave")
// returns "SHIRE"
Nel retro del club troverai i poeti più rinomati, una specie di area VIP. Dato che non è per tutti, il procedimento della porta sul retro è un po' più contorto.
", please" alla fine della parola formata dalle lettere.Ad esempio, la poesia menzionata prima è anche un telestich: l'ultima lettera di ogni frase forma una parola.
Stands so high
Huge hooves too
Impatiently waits for
Reins and harness
Eager to leave
Quando la guardia recita la poesia, la dividerai in singole righe, rimuoverai gli eventuali spazi finali e risponderai con le prime lettere di ogni riga, cioè ["h", "o", "r", "s", "e"].
La guardia ti darà poi la parola formata dall'array di lettere con cui hai risposto, così che tu la converta in una parola con l'iniziale maiuscola e aggiunga ", please".
Alla fine la password che restituirai è "horse, please" ed entrerai.
Implementa la funzione backDoorPassword che prende una stringa che rappresenta la poesia.
La funzione deve restituire la password che daresti alla guardia.
backDoorPassword("Stands so high\nHuge hooves too\nImpatiently waits for\nReins and harness\nEager to leave")
// returns "horse, please"
Nella sala sul retro del club c'è un'altra porta che conduce alla stanza segreta, dove possono entrare solo i poeti di altissimo livello.
"!" alla fine della parola formata dalle lettere.Ad esempio, una versione modificata della poesia menzionata prima segue questo schema:
Stands so high
Huge hooves too
Impatiently waits for
Rider with harness
Eager to leave
Quando la guardia recita la poesia, la dividerai in singole righe, rimuoverai gli eventuali spazi finali e risponderai con le iesime lettere di ogni riga, cioè ["S", "u", "p", "e", "r"].
La guardia ti darà poi la parola formata dall'array di lettere con cui hai risposto, così che tu la converta in maiuscolo e aggiunga "!".
Alla fine la password che restituirai è SUPER! ed entrerai.
Implementa la funzione secretRoomPassword che prende una stringa che rappresenta la poesia.
La funzione deve restituire la password che daresti alla guardia.
secretRoomPassword("Stands so high\nHuge hooves too\nImpatiently waits for\nRider with harness\nEager to leave")
// returns "SUPER!"
Iscriviti a Exercism per imparare e padroneggiare Swift con 35 concetti116 esercizi e il mentoring di persone reali, tutto gratis.