swift 2中引入的可选模式的优点/用例有哪些?

Qiu*_*ang 4 pattern-matching switch-statement optional swift swift2

对于简单的情况,if let或者guard我没有看到优势,

if case let x? = someOptional where ... {
  ...
}

//I don't see the advantage over the original if let

if let x = someOptional where ... {
  ...
}
Run Code Online (Sandbox Code Playgroud)

对于for-case-let简化使用可选集合的情况,我真的希望swift可以更进一步:

for case let x? in optionalArray {
  ...
}

//Wouldn't it be better if we could just write

for let x? in optionalArray {
  ...
}
Run Code Online (Sandbox Code Playgroud)

谷歌一段时间之后我认为唯一有用的案例是" Swift 2模式匹配:解开多个选项 ":

switch (username, password) {
case let (username?, password?):
    print("Success!")
case let (username?, nil):
    print("Password is missing")
...
Run Code Online (Sandbox Code Playgroud)

那么引入可选模式的任何其他优点呢?

jtb*_*des 5

我相信你把两个不同的概念混为一谈.不可否认,语法不是直观的,但我希望它们的用法在下面说明.(我建议阅读有关Swift编程语言中模式的页面.)

case 条件

"案件条件"是指写作的能力:

  • if case «pattern» = «expr» { ... }
  • while case «pattern» = «expr» { ... }
  • for case «pattern» in «expr» { ... }

这些特别有用,因为它们允许您在不使用的情况下switch提取枚举值.

你的例子if case let x? = someOptional ...就是一个有效的例子,但我相信它对除了Optional之外枚举最有用.

enum MyEnum {
    case A
    case B(Int)
    case C(String)
}

func extractStringsFrom(values: [MyEnum]) -> String {
    var result = ""

    // Without case conditions, we have to use a switch
    for value in values {
        switch value {
        case let .C(str):
            result += str
        default:
            break
        }
    }

    // With a case condition, it's much simpler:
    for case let .C(str) in values {
        result += str
    }

    return result
}
Run Code Online (Sandbox Code Playgroud)

实际上,您可以使用几乎任何您通常在a中使用的模式的大小写条件switch.有时可能很奇怪:

  • if case let str as String = value { ... }(相当于if let str = value as? String)
  • if case is String = value { ... }(相当于if value is String)
  • if case 1...3 = value { ... }(相当于if (1...3).contains(value)if 1...3 ~= value)

可选的模式,又名 let x?

另一方面,可选模式是一种模式,除了简单之外,它还允许您在上下文中展开选项if let.使用时,它是特别有用switch(类似于您的用户名/密码为例):

func doSomething(value: Int?) {
    switch value {
    //case 2:  // Not allowed
    case 2?:
        print("found two")

    case nil:
        print("found nil")

    case let x:
        print("found a different number: \(x)")
    }
}
Run Code Online (Sandbox Code Playgroud)