swift switch语句在可选的布尔元组上

时间:2014-06-27 19:06:33

标签: switch-statement swift tuples optional

我无法弄清楚如何在交换机内部的元组内使用选项。下面..Some(let ...)...语法作为非元组工作,但在元组内我得到预期的分隔符:(

var dict = Dictionary<String,Bool>()
dict["a"] = true

switch (dict["a"],dict["b") {
case (.Some(let a) where !a, .Some(let b) where b):
  println("false/nil, true")
case (.Some(let a) where a, .Some(let b) where !b):
  println("true, false/nil")

我想避免做以下事情

    if let a = self.beaconList["a"] {
        if let b = self.beaconList["b"] {
            // a, b
        } else {
            // a, !b
        }
    } else {
        if let b = self.beaconList["b"] {
            // !a, b
        } else {
            // !a, !b
        }
    }

3 个答案:

答案 0 :(得分:17)

有很多方法可以做到这一点,但是为了修复你试图按字面意思做的语法,你需要显式地取消选择Optional,或者通过匹配.Some(false),或者用@解包它! (我认为这有点奇怪,你会看到)

var dict = Dictionary<String,Bool>()
dict["a"] = true
dict["c"] = false

func matchOneOrTheOtherWithOptionals(a: Bool?, b: Bool?) -> String {
    switch (a, b) {
    case (.Some(true), let b) where b == .None || !b!: // gross
        return "a was true, but b was None or false"
    case (let a, .Some(true)) where a == .None || a == .Some(false):
        return "a was None or false and b was true"
    default:
        return "They both had a value, or they were both missing a value"
    }
}

matchOneOrTheOtherWithOptionals(true, .None) // "a was true, but b was None or false"
matchOneOrTheOtherWithOptionals(true, false) // "a was true, but b was None or false"
matchOneOrTheOtherWithOptionals(.None, true) // "a was None or false and b was true"
matchOneOrTheOtherWithOptionals(false, true) // "a was None or false and b was true"

matchOneOrTheOtherWithOptionals(false, false) // "They both had a value, or they were both missing a value"
matchOneOrTheOtherWithOptionals(true, true) // "They both had a value, or they were both missing a value"
matchOneOrTheOtherWithOptionals(.None, .None) // "They both had a value, or they were both missing a value"

您还可以尝试以下方法:

func noneToFalse(bool: Bool?) -> Bool {
    if let b = bool {
        return b
    } else {
        return false
    }
}

func matchOneOrTheOther(a: Bool, b: Bool) -> String {
    switch (a, b) {
    case (true, false):
        return "a is true, b was false or None"
    case (false, true):
        return "a was false/None, b was true"
    default:
        return "both were true, or both were false/None"
    }
}

matchOneOrTheOther(noneToFalse(dict["a"]), noneToFalse(dict["b"]))

以下是我在撰写此答案时使用的游乐场的要点:https://gist.github.com/bgrace/b8928792760159ca58a1

答案 1 :(得分:2)

简化!

var dict = Dictionary<String,String>()

dict["a"] = "the letter a"

switch (dict["a"],dict["b"]) {
  case (.None, let b):
    println("false/nil, true \(b)")
  case (let a, .None):
    println("true, false/nil \(a)")
  default:
    println("don't know") 
}

答案 2 :(得分:-1)

接受的答案已过期。所以我在Swift 5中重写了它。

    var dict = Dictionary<String,Bool>()
    dict["a"] = true
    dict["c"] = false

    func matchOneOrTheOtherWithOptionals(_ a: Bool?, _ b: Bool?) -> String {
        switch (a, b) {
        case (.some(true), .none), (.some(true), .some(false)):
            return "a was true, but b was None or false"
        case (.none, .some(true)), (.some(false), .some(true)):
            return "a was None or false and b was true"
        default:
            return "They both had a value, or they were both missing a value"
        }
    }

    let xs: [Bool?] = [true, false, .none]
    for a in xs {
        for b in xs {
            print("a = \(String(describing: a)), b=\(String(describing: b))")
            print(matchOneOrTheOtherWithOptionals(a,b))
        }
    }