web-dev-qa-db-fra.com

Sinon laisser entrer Swift

y a-t-il un moyen de nier le "si laissé" rapidement? Cela me semble idiot:

    if let type = json.type  {

    } else {
        XCTFail("There is no type in the root element")
    }

Je ne peux pas utiliser XCTAssertNotNil, car json.type est une énumération.

enum JSONDataTypes {
    case Object
    case Array
    case Number
    case String
}

Merci beaucoup

EDIT: c'est un:

var type: JSONDataTypes? = nil
41
Peter Shaw

Swift 2.0 (Xcode 7) et versions ultérieures ont la nouvelle instruction guard, qui fonctionne comme un "sinon laissé" - vous pouvez conditionnellement lier une variable dans le reste de la portée englobante, en gardant la "bonne chemin "dans votre code le moins indenté.

guard let type = json.type else {
    XCTFail("There is no type in the root element")
}
// do something with `type` here

Le problème est que la clause else d'un guard doit quitter cette portée (car sinon vous tomberiez dans le code après cette clause, où les variables gardées, comme type ci-dessus, ne sont pas liés). Il doit donc se terminer par quelque chose comme return, break, continue ou une fonction connue du compilateur pour ne jamais revenir (c'est-à-dire annotée @noreturn, comme abort()... Je ne me souviens pas par inadvertance si cela inclut XCTFail, mais cela devrait ( déposer un bug s'il ne l'est pas ).

Pour plus de détails, voir Early Exit in The Swift Programming Language .


Quant aux trucs vraiment anciens ... Il n'y a pas de forme négative de if-let dans Swift 1.x. Mais puisque vous travaillez avec XCTest de toute façon, vous pouvez simplement faire tester la partie optionnelle d'une expression d'assertion:

XCTAssert(json.type != nil, "There is no type in the root element")
37
rickster

Voici comment procéder:

if json.type == nil {
  // fail
}
23
Abhi Beckert

Une autre alternative que j'ai utilisée plusieurs fois:

switch json.type
{
    case .None: // ...
    case .Some(.Object): // ...
    case .Some(.Array):  // ...
    case .Some(.Number): // ...
    case .Some(.String): // ...
}

Depuis le ? est en fait Optional<T> qui est une énumération à part entière, définie comme:

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

    ...
}
2
Can