【问题标题】:Swift Error: Binary operator '&&' cannot be applied to two 'Bool' operandsSwift 错误:二元运算符“&&”不能应用于两个“布尔”操作数
【发布时间】:2016-01-23 18:42:07
【问题描述】:

显然必须有一种方法来 AND 或 OR 多个布尔值。

我在尝试编写这样的函数时遇到此错误...

func isLocationWithinView(location: CGPoint, view: UIView) {
    //        return (location.x >= CGRectGetMinX(view.frame)) && (location.x <= CGRectGetMaxX(view.frame)) && (location.y >= CGRectGetMinY(view.frame)) && (location.y <= CGRectGetMaxY(view.frame))
    var a = true
    var b = false
    return a && b // Error: Binary operator '&&' cannot be applied to two 'Bool' operands
}

解决办法是什么?

【问题讨论】:

  • 您的函数签名中缺少返回类型 ... -&gt; Bool。 (这个错误有点误导:但没有指定返回类型,函数需要返回类型()(空元组),而你返回一个布尔值)。

标签: swift


【解决方案1】:

该错误具有误导性:核心是您在函数签名中缺少返回类型... -&gt; Bool,因此尝试将布尔值分配给空元组类型()(使用没有明确的返回类型,该函数期望返回为空元组类型())。

对于将布尔值分配给非布尔类型的任何尝试,您都可以重现此误导性错误,其中布尔值是在与无效分配相同的表达式中执行逻辑 AND/OR 表达式的结果:

var a : () = (true && false)    /* same error */
var b : Int = (true && false)   /* same error */
var c : () = (true || false)    /* same error (for binary op. '||') */

而如果您将 AND/OR 操作包装在一个闭包中,或者只是将它们分配给一个中间布尔变量,您就会丢失混淆的错误消息并显示实际错误。

var d : () = { _ -> Bool in return (true && false) }()
    /* Cannot convert call result type 'Bool' to expected type '()' */
var e = true && false
var f : () = e
    /* Cannot convert value of type 'Bool' to expected type '()' */

现在为什么你会得到这个误导性错误。两个逻辑运算符 &amp;&amp;|| 都是通过对其右侧表达式 (rhs) 的条件评估来实现的,因此 rhs 只有在左侧 (lhs) 的情况下才能被延迟评估对于 &amp;&amp;/|| 运算符,分别计算为 true/false

/* e.g. the AND '&&' logical binary infix operator */
func &&(lhs: BooleanType, @autoclosure rhs: () -> BooleanType) -> Bool {
    return lhs.boolValue ? rhs().boolValue : false
}

由于lhs 本身对于后面的赋值无效,可能是惰性闭包rhs 抛出了一个由Bool 类型到() 的“外部”无效赋值引起的错误,但是抛出的错误( “无法应用二进制操作 '&amp;&amp;'...”) 不是 &amp;&amp; 调用失败的实际根源。

为了验证,我们可以实现自己的非惰性 AND 运算符,例如 &amp;&amp;&amp;,并且正如预期的那样,我们不会收到相同的混淆错误:

infix operator &&& {
    associativity right
    precedence 120
}
func &&&(lhs: BooleanType, rhs: BooleanType) -> Bool {
    return lhs.boolValue ? rhs.boolValue : false
}
var g : () = false &&& true
/* Cannot convert value of type 'Bool' to expected type '()' */

【讨论】:

  • 这个答案应该被接受。此错误消息在Swift 2 中具有误导性,希望它会在未来的版本中得到修复,就像之前与误导性块相关的错误一样。
  • 在 Swift 3 中还是一样
【解决方案2】:

虽然其他答案有一些非常有趣的观点,但在这种特殊情况下,向函数添加返回类型可以解决问题。

func isLocationWithinView(location: CGPoint, view: UIView) -> Bool {
    let a = true
    let b = false
    return a && b // Error: Binary operator '&&' cannot be applied to two 'Bool' operands
}

如果a 为真,这将返回true,如果不是,它将查看b(惰性求值)。

【讨论】:

  • 如果 a 和 b 都为真,这不会返回真吗?我错过了什么
  • 是的,它要求两者都为真。我将不得不编辑这篇文章或删除
猜你喜欢
  • 1970-01-01
  • 2015-08-29
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
相关资源
最近更新 更多