2016-06-10 15 views
9

Mi sono imbattuto in questo codice che fa parte di un'implementazione Swift di un elenco collegato nel Swift Algorithm Club. Durante l'implementazione l'autore utilizza case let seguendo una dichiarazione while prima di scartare un opzionale. Non ho mai visto la parola chiave usata al di fuori del contesto di un'istruzione switch, e mi chiedo che cosa fa esattamente? In qualche modo getta la parte let next? = node.next su true o false, forse a seconda che lo next? diventi nullo o no?Cosa significa "caso" senza istruzione switch in Swift?

public var last: Node? { 
    if var node = head { 
     while case let next? = node.next { 
      node = next 
     } 
     return node 
    } else { 
     return nil 
    } 
} 
+0

Correlati: http://stackoverflow.com/questions/30720289/swift-2-pattern-matching-in-if. –

+0

Anche correlati: http://stackoverflow.com/questions/36880109/what-are-the-advantages-use-cases-of-optional-patterns-introduced-in-swift-2/36881836#36881836 – jtbandes

risposta

13

Questo è il Optional Pattern. Verifica e decomprime un Optional, eseguendo il condizionale solo se lo Optional è diverso da zero.

La parola chiave case è necessaria perché segue la sintassi originale switch ... case. Il case verifica un modello e se corrisponde, viene eseguita la seguente istruzione. Nel tuo esempio lo let next? è il modello. Se il valore viene scartato e assegnato, corrispondono le corrispondenze case e il codice viene eseguito.

Dalla documentazione:

opzionale modello

Un modello opzionale partite valori avvolto in un caso in cui alcuni (Wrapped) di un optional o ImplicitlyUnwrappedOptional enumerazione. I modelli facoltativi sono costituiti da un modello identificativo seguito immediatamente da un punto interrogativo e visualizzato negli stessi luoghi come modelli di casi di enumerazione.

Poiché modelli opzionali sono zucchero sintattico per i modelli opzionali e casi censimento ImplicitlyUnwrappedOptional, il seguente sono equivalenti:

let someOptional: Int? = 42 
// Match using an enumeration case pattern 
if case .Some(let x) = someOptional { 
    print(x) 
} 

// Match using an optional pattern 
if case let x? = someOptional { 
    print(x) 
} 

Il modello opzionale fornisce un modo conveniente per scorrere un matrice di valori opzionali in un for-in, eseguendo il corpo di il ciclo solo per elementi non nulli.

let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5] 
// Match only non-nil values 
for case let number? in arrayOfOptionalInts { 
    print("Found a \(number)") 
} 
// Found a 2 
// Found a 3 
// Found a 5 
+5

Questo mi sembra per spiegare (abbastanza bene) che cos'è un modello opzionale, ma * non * perché il "caso" è necessario, desiderabile o persino possibile. Dopotutto, quello che la domanda stava chiedendo. – paxdiablo

+4

Gli optionals in swift sono enumerazioni (generiche) dietro le quinte, e ogni possibile valore che un enum può prendere è denominato "caso" (in base all'istruzione 'switch' comunemente usata per selezionare uno dei molti valori possibili). I due casi dell'optional sono '.None' (quando' nil') e '.Some' (quando non-nil, con il valore spostato come valore associato del caso enum). Immagino sia per questo che questa sintassi usa la parola chiave 'case', anche se non è un'istruzione' switch'. –

+0

Il link che ho dato spiega il "perché", c'era troppo da citare. Ho aggiunto una semplice spiegazione su "perché" è necessaria la parola chiave, ma la documentazione va più nel dettaglio. – ColGraff

3

Swift 2 ha preso il paradigma modello da switch/case dichiarazioni e ha permesso di essere utilizzato in altri contesti (if, while e così via).

Quindi ora, piuttosto che semplici confronti, è possibile utilizzare anche questi confronti di pattern matching in condizionali.

Come esempio, piuttosto che:

if (a >= 0) and (a <= 255) 

si può invece utilizzare:

if case 0...255 = a 

Questo è un esempio banale ma può diventare molto più utile una volta ci si rende conto piuttosto grande numero di modello opzioni di corrispondenza disponibili per te.

+0

Penso che in questo caso sia preferito '0 ... 255 = ~ a'. Probabilmente useresti solo 'caso' per il contenimento di' Range' in un 'caso-interruttore'. – BallpointBen

Problemi correlati