在Swift中,两个布尔操作数不能应用二元运算符"&="。

10

我正在尝试进行多个检查并将结果积累在一个Bool中:

我的代码如下:

 var validParams = login.characters.count > 4;
 validParams &= password.characters.count > 6;
 validParams &= ...
 // more validations
 if (validParams) {...}

但我收到了错误提示 二元运算符'&='不能应用于两个 'Bool' 操作数

如何以更简洁的方式完成这项工作或重写代码?


@Anbu.Karthik 不是,这绝对不是链接问题的重复。对于这个问题的答案是,&=是一个位运算符,不能应用于Bool - JeremyP
2
@JeremyP - 哦,抱歉我的兄弟。 - Anbu.Karthik
2个回答

8

&=是一种按位操作符,只能应用于整数类型。实际上不存在&&=,因为存在短路效应。你需要编写

validParams = validParams && ...

因为短路而实际上不存在”是什么意思?你可以实现一个&&=运算符来进行短路比较,参见我的回答 - Hamish
@Hamish 是的,你可以实现它,但我认为它没有被实现,因为短路会使副作用变得混乱。在 C 中也没有 &&= - JeremyP
我并不真正明白 b &&= x() 的副作用会比 b = b && x() 更令人困惑,但我猜每个人都有自己的看法。 - Hamish
@Hamish 第二种方式可能被认为更明显地进行短路处理。 - JeremyP

5

正如@JeremyP所说,&=是一个原地按位与运算符,仅适用于整数类型。但是,您可以定义自己的&&=运算符进行原地逻辑与操作:

infix operator &&= : AssignmentPrecedence

func &&=(lhs: inout Bool, rhs: @autoclosure () -> Bool) {
    // although it looks like we're always evaluating rhs here, the expression "rhs()" is
    // actually getting wrapped in a closure, as the rhs of && is @autoclosure.
    lhs = lhs && rhs()
}

您可以简单地像这样使用它:
func someExpensiveFunc() -> Bool {
    // ...
    print("some expensive func called")
    return false
}

var b = false

b &&= someExpensiveFunc() // someExpensiveFunc() not called, as (false && x) == false.
print(b) // false

b = true

b &&= someExpensiveFunc() // someExpensiveFunc() called, as (true && x) == x
print(b) // false

正如您所看到的,由于我们将 &&=rhs: 参数设置为 @autoclosure 参数,因此当 lhsfalse 时,我们可以进行短路计算。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接