组合多个 Bool return 值而不短路
Combining multiple Bool return values without shortcircuiting
Swift 2 对 Bool
值使用按位运算符有限制。这是可以接受的。在 ObjC 中,当您需要执行每个操作数时使用它非常有用。例如:
a.isFoo() & b.isFoo() & c.isFoo()
在这种情况下,使用按位 & 将执行每个方法。
如果我使用逻辑运算符&&,它将执行第一个,如果它为假,表达式将return假而不执行其他两个操作数.
我想找到与 & 相同的优雅方式,在 Swift 中使用 Bool
。可能吗?
您在 Objective-C 中所做的不是 "elegant"。这很卑鄙,你不应该这样做。如果你想调用三个方法,就调用那三个方法!但是形成一个布尔表达式,你应该使用逻辑运算符,而不是位运算符。所以,例如:
let (ok1, ok2, ok3) = (a.isBool(), b.isBool(), c.isBool())
let ok = ok1 && ok2 && ok3
没有这样的特殊运算符,但我可能会这样做:
if ![a.isBool(), b.isBool(), c.isBool()].contains(false) {
或者只是
let aCondition = a.isBool()
let bCondition = b.isBool()
let cCondition = c.isBool()
if aCondition && bCondition && cCondition {
但您也可以为此定义自己的运算符。
您可以使用对方法调用数组的 reduce
操作来模拟相同的行为,例如
/* example setup */
struct Foo {
let bar: Bool
init(_ bar: Bool) { self.bar = bar }
func isTrue() -> Bool { print("\(bar) foo!"); return bar }
}
let a = Foo(false)
let b = Foo(false)
let c = Foo(true)
/* naturally all three method calls will execute to construct the boolean
array, whereafter reduce will evaluate the combined conditional statement */
if [a.isTrue(), b.isTrue(), c.isTrue()].reduce(true, combine: { [=10=] && }) {
print("Reached this ...")
} /* false foo!
false foo!
true foo! */
let d = Foo(true)
let e = Foo(true)
let f = Foo(true)
if [d.isTrue(), e.isTrue(), f.isTrue()].reduce(true, combine: { [=10=] && }) {
print("Reached this ...")
} /* true foo!
true foo!
true foo!
Reached this ... */
或例如将您的方法作为可变参数提供给执行方法执行和组合条件
的函数
func foo(calls: (() -> Bool)...) -> Bool {
return calls.map{ [=11=]() }.reduce(true, combine: { [=11=] && })
}
let a = Foo(false)
let b = Foo(false)
let c = Foo(true)
if foo(a.isTrue, b.isTrue, c.isTrue) {
print("Reached this ...")
} /* false foo!
false foo!
true foo! */
let d = Foo(true)
let e = Foo(true)
let f = Foo(true)
if foo(d.isTrue, e.isTrue, f.isTrue) {
print("Reached this ...")
} /* true foo!
true foo!
true foo!
Reached this ... */
let values = [a.isFoo(), b.isFoo(), c.isFoo()]
let result = values.allSatisfy { [=10=] }
Swift 2 对 Bool
值使用按位运算符有限制。这是可以接受的。在 ObjC 中,当您需要执行每个操作数时使用它非常有用。例如:
a.isFoo() & b.isFoo() & c.isFoo()
在这种情况下,使用按位 & 将执行每个方法。
如果我使用逻辑运算符&&,它将执行第一个,如果它为假,表达式将return假而不执行其他两个操作数.
我想找到与 & 相同的优雅方式,在 Swift 中使用 Bool
。可能吗?
您在 Objective-C 中所做的不是 "elegant"。这很卑鄙,你不应该这样做。如果你想调用三个方法,就调用那三个方法!但是形成一个布尔表达式,你应该使用逻辑运算符,而不是位运算符。所以,例如:
let (ok1, ok2, ok3) = (a.isBool(), b.isBool(), c.isBool())
let ok = ok1 && ok2 && ok3
没有这样的特殊运算符,但我可能会这样做:
if ![a.isBool(), b.isBool(), c.isBool()].contains(false) {
或者只是
let aCondition = a.isBool()
let bCondition = b.isBool()
let cCondition = c.isBool()
if aCondition && bCondition && cCondition {
但您也可以为此定义自己的运算符。
您可以使用对方法调用数组的 reduce
操作来模拟相同的行为,例如
/* example setup */
struct Foo {
let bar: Bool
init(_ bar: Bool) { self.bar = bar }
func isTrue() -> Bool { print("\(bar) foo!"); return bar }
}
let a = Foo(false)
let b = Foo(false)
let c = Foo(true)
/* naturally all three method calls will execute to construct the boolean
array, whereafter reduce will evaluate the combined conditional statement */
if [a.isTrue(), b.isTrue(), c.isTrue()].reduce(true, combine: { [=10=] && }) {
print("Reached this ...")
} /* false foo!
false foo!
true foo! */
let d = Foo(true)
let e = Foo(true)
let f = Foo(true)
if [d.isTrue(), e.isTrue(), f.isTrue()].reduce(true, combine: { [=10=] && }) {
print("Reached this ...")
} /* true foo!
true foo!
true foo!
Reached this ... */
或例如将您的方法作为可变参数提供给执行方法执行和组合条件
的函数func foo(calls: (() -> Bool)...) -> Bool {
return calls.map{ [=11=]() }.reduce(true, combine: { [=11=] && })
}
let a = Foo(false)
let b = Foo(false)
let c = Foo(true)
if foo(a.isTrue, b.isTrue, c.isTrue) {
print("Reached this ...")
} /* false foo!
false foo!
true foo! */
let d = Foo(true)
let e = Foo(true)
let f = Foo(true)
if foo(d.isTrue, e.isTrue, f.isTrue) {
print("Reached this ...")
} /* true foo!
true foo!
true foo!
Reached this ... */
let values = [a.isFoo(), b.isFoo(), c.isFoo()]
let result = values.allSatisfy { [=10=] }