web-dev-qa-db-ja.com

Swift:スイッチケースのオプション値に対するテスト

Swiftでは、オプションの内容に対して切り替えられる値をテストするswitchステートメントにケースを書くにはどうすればよいですか?オプションにnilが含まれている場合はケースをスキップしますか?

これがどのように見えるか想像してみてください:

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
}

このように正確に記述すると、コンパイラはsomeOptionalがアンラップされていないことを訴えますが、!を最後に追加して明示的にアンラップすると、もちろんランタイムエラーが発生しますsomeOptionalにはnilが含まれます。 ?の代わりに!を追加することは理にかなっていますが(オプションの連鎖の精神では)、コンパイラエラーはなくなりません(つまり、実際にはオプションをアンラップしません) )。

82
George WS

オプションはこのようなenumです:

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

    // ...
}

したがって、通常どおりに一致させることができます 「関連付けられた値」 一致パターン:

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")
}

guard expression を使用して、someValueから一致させたい場合:

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

そしてfor Swift> 2.0

switch someValue {
case let val where val == someOptional:
    print("matched")
default:
    print("didn't match; default")        
}
105
rintaro

Xcode 7(ベータ1リリースノートより)では、「新しい_x?_パターンを使用して、.Some(x)の同義語としてオプションとのパターンマッチを行うことができます。」これは、Xcode 7および後で rintaroの答え の次のバリエーションも機能します。

_switch someOptional {
case someValue?:
    print("the value is \(someValue)")
case let val?:
    print("the value is \(val)")
default:
    print("nil")
}
_
45

Swift 4を使用できますOptional:ExpressibleByNilLiteralof Appleオプションでラップする

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

enum MyEnum {
    case normal
    case cool
}

some

let myOptional: MyEnum? = MyEnum.normal

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

    case .none: 
    break

    default:
    break
}

なし

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 MyEnum {
    case normal(myValue: String)
    case cool
}

何らかの値

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