Nozioni di base
Hello World
import Foundation print("Hello, World!")
Costanti e variabili
let name = "Swift" // constant (immutable) var count = 0 // variable (mutable) count += 1 let pi: Double = 3.14 // explicit type annotation
Commenti
// single-line comment /* multi-line comment */ /// documentation comment (Markdown supported)
Tipi
Tipi di base
IntIntero di dimensione piattaforma (64-bit sui sistemi moderni)
DoubleVirgola mobile a 64 bit (preferito rispetto a Float)
FloatVirgola mobile a 32 bit
Booltrue / false
StringStringa Unicode, tipo valore
CharacterSingolo cluster grafema esteso
Inferenza di tipo e conversione
let score = 95 // inferred as Int let gpa = 3.8 // inferred as Double let total = Double(score) + gpa // explicit conversion let label = "Score: \(score)" // string interpolation
Tuple
let point = (x: 3, y: 5) print(point.x) // named access let (x, y) = point // decompose let (first, _) = point // ignore second value
Alias di tipo
typealias Coordinate = (Double, Double) let origin: Coordinate = (0.0, 0.0)
Flusso di controllo
If / Else
if score > 90 { print("A") } else if score > 80 { print("B") } else { print("C") }
Switch
switch grade { case "A": print("excellent") case "B", "C": print("passing") default: print("unknown") }
Cicli
for i in 0..<5 { } // half-open range for name in names { } // collection for (i, val) in list.enumerated() { } while condition { } repeat { } while condition // do-while
Guard
func process(value: Int?) { guard let v = value, v > 0 else { return } print(v) // v is unwrapped and in scope }
Funzioni
Funzione di base
func greet(name: String) -> String { return "Hello, \(name)!" } greet(name: "Alice")
Etichette degli argomenti
func move(from start: Int, to end: Int) -> Int { return end - start } move(from: 0, to: 10) // external labels func add(_ a: Int, _ b: Int) -> Int { a + b }
Parametri predefiniti e variadici
func join(_ items: String..., separator: String = ", ") -> String { items.joined(separator: separator) } join("a", "b", "c")
Parametri inout
func double(_ x: inout Int) { x *= 2 } var num = 5 double(&num) // num is now 10
Closure
Sintassi delle closure
let double = { (x: Int) -> Int in return x * 2 } let nums = [3, 1, 2] let sorted = nums.sorted { $0 < $1 } let mapped = nums.map { $0 * 10 }
Trailing closure
UIView.animate(withDuration: 0.3) { view.alpha = 0.0 }
Cattura di valori
func makeCounter() -> () -> Int { var count = 0 return { count += 1; return count } } let counter = makeCounter() // counter() => 1, 2, ...
Classi e struct
Struct (tipo valore)
struct Point { var x: Double var y: Double } var p = Point(x: 1, y: 2) // auto memberwise init
Class (tipo riferimento)
class Vehicle { var speed: Double = 0 init(speed: Double) { self.speed = speed } } class Car: Vehicle { var gear: Int = 1 }
Struct vs Class
structTipo valore, copiato all'assegnazione, senza ereditarietà
classTipo riferimento, condiviso per riferimento, supporta l'ereditarietà
mutatingParola chiave richiesta per i metodi struct che modificano self
deinitDeinizializzatore solo per classi (chiamato prima della deallocazione)
Protocolli
Definizione e conformità
protocol Drawable { var description: String { get } func draw() } struct Circle: Drawable { /* implement required members */ }
Estensioni di protocollo
extension Drawable { func log() { print("Drawing: \(description)") } } // all Drawable conformers get log() for free
Protocolli comuni
EquatableConfronto con == e !=
ComparableOrdinamento con <, >, <=, >=
HashableUtilizzabile come chiave Dictionary o in Set
CodableEncodable + Decodable (JSON, Plist)
CustomStringConvertibleProprietà description personalizzata
IdentifiableRichiede la proprietà id (SwiftUI)
Opzionali
Dichiarazione degli opzionali
var name: String? = "Alice" // may contain String or nil var age: Int? = nil // currently nil let count: Int = 5 // non-optional, never nil
Unwrapping
if let n = name { print(n) } // optional binding guard let n = name else { return } // guard let n = name ?? "Unknown" // nil coalescing let n = name! // force unwrap (crashes if nil)
Concatenamento opzionale
let count = user?.address?.zip?.count // returns nil if any link in the chain is nil user?.save() // called only if user is non-nil
Map opzionale
let length = name.map { $0.count } // Int? let upper = name.flatMap { $0.isEmpty ? nil : $0.uppercased() }
Enum
Enum di base
enum Direction { case north, south, east, west } var heading = Direction.north heading = .east // type inferred
Valori associati
enum Result { case success(data: String) case failure(code: Int, message: String) } if case .failure(let code, _) = r { print(code) }
Valori raw
enum Planet: Int { case mercury = 1, venus, earth, mars } let p = Planet(rawValue: 3) // Optional(.earth) print(Planet.earth.rawValue) // 3
Metodi sugli enum
enum Suit: String, CaseIterable { case hearts, diamonds, clubs, spades } Suit.allCases.forEach { print($0.rawValue) }
Gestione degli errori
Definizione degli errori
enum NetworkError: Error { case badURL case timeout(seconds: Int) case serverError(code: Int) }
Generazione e cattura degli errori
func fetch(url: String) throws -> Data { guard url.hasPrefix("https") else { throw NetworkError.badURL } return Data() } do { let data = try fetch(url: "https://example.com") } catch { print("Error: \(error)") }
Varianti di try
tryDeve essere dentro do-catch, propaga l'errore
try?Restituisce un opzionale, nil in caso di errore
try!Forza try, va in crash in caso di errore
throwsLa funzione può generare errori
rethrowsGenera errori solo se la closure argomento li genera