web-dev-qa-db-fra.com

Swift: test par rapport à la valeur optionnelle dans un boîtier de commutateur

Dans Swift, comment puis-je écrire un cas dans une instruction switch qui teste la valeur en cours de commutation par rapport au contenu d'un optionnel, en sautant le cas si 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 cela, le compilateur se plaint que someOptional n’est pas décompressé, mais si je le décompresse explicitement en ajoutant ! jusqu’à la fin, j’ai bien sûr une erreur d’exécution à tout moment someOptional contient nil. Ajouter ? au lieu de ! aurait un sens pour moi (dans l’esprit du chaînage optionnel, je suppose), mais ne faisait pas disparaître l’erreur du compilateur (c’est-à-dire qu’il ne déroulait pas réellement l’optif).

82
George WS

Facultatif est juste un enum comme ceci:

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

    // ...
}

Donc, vous pouvez les faire correspondre 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 une correspondance de someValue, utilisez 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")        
}
105
rintaro

A partir de Xcode 7 (à partir des notes de version beta 1), "un nouveau modèle x? Peut être utilisé pour rechercher des correspondances entre les options, comme synonyme de .Some(x).". Cela signifie que dans Xcode 7 et plus tard, la variante suivante de réponse de rintaro fonctionnera également:

switch someOptional {
case someValue?:
    print("the value is \(someValue)")
case let val?:
    print("the value is \(val)")
default:
    print("nil")
}
45
Slipp D. Thompson

Dans Swift 4 , vous pouvez utiliser Facultatif: ExpressibleByNilLiteral de Apple pour envelopper facultatif

https://developer.Apple.com/documentation/Swift/optional

Exemple

enum MyEnum {
    case normal
    case cool
}

un peu

let myOptional: MyEnum? = MyEnum.normal

switch smyOptional {
    case .some(.normal): 
    // Found .normal enum
    break

    case .none: 
    break

    default:
    break
}

aucun

let myOptional: MyEnum? = nil

switch smyOptional {
    case .some(.normal): 
    break

    case .none: 
    // Found nil
    break

    default:
    break
}

default

let myOptional: MyEnum? = MyEnum.cool

switch smyOptional {
    case .some(.normal): 
    break

    case .none: 
    break

    default:
    // Found .Cool enum
    break
}

Enum avec valeur

enum MyEnum {
    case normal(myValue: String)
    case cool
}

une valeur

let myOptional: MyEnum? = MyEnum.normal("BlaBla")

switch smyOptional {
case .some(.normal(let myValue)) where myValue == "BlaBla":
    // Here because where find in my myValue "BlaBla"
    break

// Example for get value
case .some(.normal(let myValue)):
    break

// Example for just know if is normal case enum
case .some(.normal):
    break

case .none:
    break

default:

    break
}
5
YannSteph