Подтвердить что ты не робот

Ошибка Swift: двоичный оператор '&&' не может применяться к двум операндам Bool

Очевидно, что должен быть путь к 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
}

Какое решение для этого?

4b9b3361

Ответ 1

Ошибка вводит в заблуждение: ядро ​​заключается в том, что в вашей сигнатуре функции отсутствует тип возврата ... -> 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 '()' */

Теперь, почему вы получили эту ошибочную ошибку. Оба логических оператора && и || реализуются с условной оценкой их правых выражений (rhs), так что rhs можно лениво оценить только в том случае, если левая часть (lhs) оценивается как 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, до (), но ошибка (например, "Binary op '&&' не может быть применен..." ) не является фактическим источником отказа вызова &&.

Чтобы убедиться, мы можем реализовать наш собственный нелазный оператор И, скажем &&&, и, как и ожидалось, мы не получаем ту же ошибку обфускации:

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 '()' */

Ответ 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
}

Это вернет true, если a были истинными, а если нет, это будет выглядеть b (ленивая оценка).