swift - 如何在 switch 语句中解包双选项 -- Swift

标签 swift switch-statement

xCode 10.2.1,未指定 Swift 语言(4、4.2、5)

我有两个双可选 bool 值。我想在 switch 语句中解包它们......

func evaluate() -> Bool? {
    let lhs = try? getLhs() // lhs = Bool??; getLhs() returns Bool?
    let rhs = try? getRhs() // rhs = Bool??; getRhs() returns Bool?
    switch (lhs ?? nil, rhs ?? nil) {
    case (nil, nil):
        return nil
    case (nil, rhs):
        return rhs ?? nil
    case (lhs, nil):
        return lhs ?? nil
    default:
        guard case let lhs?? = lhs, case let rhs?? = rhs  else { return nil }
        return lhs || rhs
    }
}

这行得通,但我很好奇为什么我需要双重解包默认情况? 我在想,一旦 lhs 和 rhs 从开关输入中解开,默认情况下是否可以使用 Bool?对于 lhs 和 rhs。

更新——

感谢您的回答。是的,double optional 有点矫枉过正,但我​​真正想了解的是为什么我的默认设置要求我再次展开。我不完全理解 switch 如何与 optionals 一起工作。 Alexander 帮助我理解了所有迭代,而 vacawama 为我提供了一个干净的实现。

最佳答案

This works, but I'm curious why I need to double unwrap the default case? I was thinking once the lhs and rhs get unwrapped from the switch inputs, the default case would work with a Bool? for lhs and rhs.

当您执行 lhs 时,您没有更改 lhsrhs ??零rhs ??无。您正在创造新的值(value)。因此,当您遇到 default 情况时,lhsrhs 仍然是 Bool??。您可以使用 let lhslet rhs 来捕获展开的值,就像我在下面的解决方案中所做的那样。


这是另一种方法。一些模式匹配更干净:

switch (lhs as? Bool, rhs as? Bool) {
case (nil, nil):
    return nil
case (nil, let rhs):
    return rhs
case (let lhs, nil):
    return lhs
case (let lhs?, let rhs?):
    return lhs || rhs
}

解释

使用 as? 转换 Bool?? Bool 给您留下了 Bool?。模式匹配中的 let rhslet lhs 捕获 Bool? 值,以便返回它。在最后的 case 中,let lhs?let rhs? 展开 Bool? 值得到 Bool 值,以便可以执行 ||


测试用例

test(nil, nil) // nil
test(nil, false) // false
test(nil, true) // true
test(nil, Optional(nil)) // nil
test(nil, Optional(false)) // false
test(nil, Optional(true)) // true

test(false, nil) // false
test(false, false) // false
test(false, true) // true
test(false, Optional(nil)) // false
test(false, Optional(false)) // false
test(false, Optional(true)) // true

test(true, nil) // true
test(true, false) // true
test(true, true) // true
test(true, Optional(nil)) // true
test(true, Optional(false)) // true
test(true, Optional(true)) // true

test(Optional(nil), nil) // nil
test(Optional(nil), false) // false
test(Optional(nil), true) // true
test(Optional(nil), Optional(nil)) // nil
test(Optional(nil), Optional(false)) // false
test(Optional(nil), Optional(true)) // true

test(Optional(false), nil) // false
test(Optional(false), false) // false
test(Optional(false), true) // true
test(Optional(false), Optional(nil)) // false
test(Optional(false), Optional(false)) // false
test(Optional(false), Optional(true)) // true

test(Optional(true), nil) // true
test(Optional(true), false) // true
test(Optional(true), true) // true
test(Optional(true), Optional(nil)) // true
test(Optional(true), Optional(false)) // true
test(Optional(true), Optional(true)) // true

关于swift - 如何在 switch 语句中解包双选项 -- Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57257935/

相关文章:

javascript - 为什么我的 switch 语句参数需要 boolean 值?

c++ - 得到一堆十字架初始化错误

ios - PFUser.current()?.saveInBackground 错误与 UIImage()

swift - 如何从 swift 数组中删除多个项目?

java - 二叉树 - 带开关盒

ruby-on-rails - 匹配时的情况

swift - 以编程方式添加内容时 UIView 发生变化 - Swift

Swift 2.0 Core Spotlight API - 仅搜索标题

arrays - 将 id 内的数组字符串值与 Swift 3 中的索引匹配

java - 如何用更好的解决方案替换 switch 语句 - 干净的代码提示