使用带有许多表达式的“if let ...”

时间:2014-06-09 11:01:09

标签: swift

Swift的这个成语很有道理

if let x = someDict[someKey] { ... }

然而,我真正想要的是

if let x = someDict[someKey], y = someDict[someOtherKey] { ... }

如上所述,这不是不正确的,但这个想法是否可能?

3 个答案:

答案 0 :(得分:29)

更新Swift 1.2

自Swift 1.2起,if let允许展开多个选项,因此您现在可以只编写它,如示例所示:

if let x = someDict[someKey], y = someDict[someOtherKey] { … }

您甚至可以交错条件,例如:

if let x = someDict[someKey] where x == "value", y = someDict[someOtherKey] { … }

以前在Swift 1.2之前有效

这是你如何在没有丑陋的力量上行的情况下做到这一点:

switch (dict["a"], dict["b"]) {
case let (.Some(a), .Some(b)):
    println("match")
default:
    println("no match")
}

实际上还是很啰嗦。

这是有效的,因为Type?形式的可选类型实际上是Optional<Type>的简写,这是一个看起来大致如下的枚举:

enum Optional<T> {
    case None
    case Some(T)
}

然后,您可以将模式匹配用于任何其他枚举。

编辑:我见过有人写过像这样的辅助函数(抱歉缺少归因,我不记得在哪里看到它):

func unwrap<A, B>(a: A?, b: B?) -> (A, B)? {
    switch (a, b) {
    case let (.Some(a), .Some(b)):
        return (a, b)
    default:
        return nil
    }
}

然后你可以继续使用if let结构,就像这样:

if let (a, b) = unwrap(dict["a"], dict["b"]) {
    println("match: \(a), \(b)")
} else {
    println("no match")
}

答案 1 :(得分:4)

Swift 1.2(Xcode 6.3的一部分)if let optional binding construct can bind multiple optionals中,使用与此问题相同的语法。

if let x = someDict[someKey], y = someDict[someOtherKey] { ... }

您还可以在绑定值的条件下扩展它:

if let a = foo(), b = bar(), a < b, let c = baz() { ... }

用于处理多个可选绑定的switch模式(如this answer中所示)仍然有效。虽然使用if let保护条件你可能会发现它的用例较少,但是如果你想要处理多个可选绑定的情况,当你测试的选项的不同子集为零时,它仍然存在。

(注意:在Swift 3之前,if let a = ..., b = ..., a < b使用where从条件中拆分绑定。)

答案 2 :(得分:1)

在Swift1.2中,您可以使用多个可选绑定。

if let x = someDict[someKey], y = someDict[someOtherKey] { ... }

请注意,y被隐式声明为常量,与x相同。上面的代码等同于以下内容。

if let x = someDict[someKey],let y = someDict[someOtherKey] { ... }

如果要将y显式声明为可变类型,只需在变量名之前键入var。

if let x = someDict[someKey],var y = someDict[someOtherKey] { ... }