Swift: test par rapport à une valeur optionnelle dans le cas d'un switch

dans Swift, Comment puis-je écrire un cas dans une instruction de switch qui teste la valeur commutée par rapport au contenu d'un optionnel , sautant sur le cas si l'optionnel contient nil ?

Voici comment j'imagine que cela pourrait ressembler:

let someValue = 5
let someOptional: Int? = nil

switch someValue {
case someOptional:
    // someOptional is non-nil, and someValue equals the unwrapped contents of someOptional
default:
    // either, someOptional is nil, or someOptional is non-nil but someValue does not equal the unwrapped contents of someOptional
}

si je l'écris exactement comme ceci, le compilateur se plaint que someOptional n'est pas déballé, mais si je le déballé explicitement en ajoutant ! à a la fin, j'obtiens bien sûr une erreur d'exécution à tout moment someOptional contient nil . Ajouter ? au lieu de ! aurait du sens pour moi (dans l'esprit du chaînage optionnel, je suppose), mais ne fait pas disparaître l'erreur du compilateur (c'est-à-dire ne déballe pas réellement l'optionnel).

70
demandé sur Honey 2014-11-15 04:30:44

2 réponses

optionnel est juste un enum comme ceci:

enum Optional<T> : Reflectable, NilLiteralConvertible {
    case None
    case Some(T)

    // ...
}

pour que vous puissiez les apparier comme d'habitude "valeurs associées " motifs correspondants:

let someValue = 5
let someOptional: Int? = nil

switch someOptional {
case .Some(someValue):
    println("the value is \(someValue)")
case .Some(let val):
    println("the value is \(val)")
default:
    println("nil")
}

si vous voulez la correspondance de someValue , en utilisant expression de garde :

switch someValue {
case let val where val == someOptional:
    println(someValue)
default:
    break
}

et pour Swift > 2.0

switch someValue {
case let val where val == someOptional:
    print("matched")
default:
    print("didn't match; default")        
}
89
répondu rintaro 2017-11-17 17:30:36

depuis le Xcode 7 (d'après les notes de version beta 1), "un nouveau motif x? peut être utilisé pour faire correspondre le motif avec les optionnels comme synonyme de .Some(x) ."Cela signifie que dans le Xcode 7 et plus tard la variation suivante de la réponse de rintaro fonctionnera aussi bien:

switch someOptional {
case someValue?:
    print("the value is \(someValue)")
case let val?:
    print("the value is \(val)")
default:
    print("nil")
}
36
répondu Slipp D. Thompson 2017-05-23 12:02:51