-
Bool 有 2 个值:
-
Bool? 有 3 个值,.none(又名 nil)和一个 .some 案例,其中包含 Bool 的 2 个可能案例中的每一个:
.some(true)
.some(false)
-
.none
-
Bool?? 有 4 个值,.none 和一个 .some 案例,包含 Bool? 的 3 种可能案例中的每一个:
.some(.some(true))
.some(.some(false))
.some(.none)
.none
为了对解进行初步近似,我们可以枚举所有可能的值:
func getLhs() throws -> Bool? { return nil }
func getRhs() throws -> Bool? { return nil }
func f() -> Bool? {
let lhs: Bool?? = try? getLhs()
let rhs: Bool?? = try? getRhs()
switch (lhs, rhs) {
case (.some(.some(true)), .some(.some(true))): return true
case (.some(.some(true)), .some(.some(false))): return true
case (.some(.some(true)), .some(.none)): return true
case (.some(.some(true)), .none): return true
case (.some(.some(false)), .some(.some(true))): return true // result of OR
case (.some(.some(false)), .some(.some(false))): return false
case (.some(.some(false)), .some(.none)): return false
case (.some(.some(false)), .none): return false
case (.some(.none), .some(.some(true))): return true
case (.some(.none), .some(.some(false))): return false
case (.some(.none), .some(.none)): return nil
case (.some(.none), .none): return nil
case (.none, .some(.some(true))): return true
case (.none, .some(.some(false))): return false
case (.none, .some(.none)): return nil
case (.none, .none): return nil
}
}
所以现在这显然很疯狂,但我们可以通过绑定变量来折叠案例:
switch (lhs, rhs) {
case let (.some(.some(l)), .some(.some(r))): return l || r
case let (.some(.some(l)), .some(.some(r))): return l || r
case let (.some(.some(l)), .some(.none)): return l
case let (.some(.some(l)), .none): return l
case let (.some(.some(l)), .some(.some(r))): return l || r
case let (.some(.some(l)), .some(.some(r))): return l || r
case let (.some(.some(l)), .some(.none)): return l
case let (.some(.some(l)), .none): return l
case let (.some(.none), .some(.some(r))): return r
case let (.some(.none), .some(.some(r))): return r
case (.some(.none), .some(.none)): return nil
case (.some(.none), .none): return nil
case let (.none, .some(.some(r))): return r
case let (.none, .some(.some(r))): return r
case (.none, .some(.none)): return nil
case (.none, .none): return nil
}
我们可以删除重复的案例:
switch (lhs, rhs) {
case let (.some(.some(l)), .some(.some(r))): return l || r
case let (.some(.some(l)), .some(.none)): return l
case let (.some(.some(l)), .none): return l
case let (.some(.none), .some(.some(r))): return r
case (.some(.none), .some(.none)): return nil
case (.some(.none), .none): return nil
case let (.none, .some(.some(r))): return r
case (.none, .some(.none)): return nil
case (.none, .none): return nil
}
然后我们可以对所有嵌套的nil 案例进行分组:
switch (lhs, rhs) {
case let (.some(.some(l)), .some(.some(r))): return l || r
case let (.some(.some(l)), .some(.none)): return l
case let (.some(.some(l)), .none): return l
case let (.some(.none), .some(.some(r))): return r
case let (.none, .some(.some(r))): return r
case (.some(.none), .some(.none)),
(.some(.none), .none),
(.none, .some(.none)),
(.none, .none):
return nil
}
然后我们可以在default 中捕获所有这些:
switch (lhs, rhs) {
case let (.some(.some(l)), .some(.some(r))): return l || r
case let (.some(.some(l)), .some(.none)): return l
case let (.some(.some(l)), .none): return l
case let (.some(.none), .some(.some(r))): return r
case let (.none, .some(.some(r))): return r
default: return nil
}
但这整件事太疯狂了
为什么你有一个throws AND 返回Optional 的函数?让函数返回一个非可选的布尔值会更好,并让nil 案例由异常之一处理。或者,您可以返回一个Result<Bool, Error>,其中一种错误情况编码为nil。
如果您必须坚持使用这些类型,switch 是完全错误的做法。您可以使用Optional.map 或Optional.flatMap,但它们也会变得毛茸茸。