2016-01-23 14 views
21

Oczywiście musi istnieć sposób na ORAZ lub LUB wielokrotne booleany.Błąd Swift: Operator binarny "&&" nie może być zastosowany do dwóch argumentów "Bool"

dostaję ten błąd próbując napisać funkcję takiego ...

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 
} 

Jakie jest rozwiązanie tego?

+9

Brakuje typu zwrotu '... -> Bool' w sygnaturze funkcji. (Błąd jest nieco mylący: ale bez określonego typu zwracanego, funkcja oczekuje typu zwrotnego '()' (pusta krotka), podczas gdy zwracasz wartość logiczną). – dfri

Odpowiedz

51

Błąd jest mylące: rdzeń jest to, że tracisz typ zwracany ... -> Bool w podpisie funkcji, stąd próby przypisać wartość logiczną do pustego krotki typu () (bez wyraźnej typ zwracany funkcja oczekuje powraca, by być pustym typem krotki: ()).

Ten błędny błąd można odtworzyć dla każdej próby przypisania wartości logicznej do typu nie-boolowskiego, gdzie wartość logiczna jest wynikiem logicznego wyrażenia AND/OR wykonywanego w tym samym wyrażeniu, co niepoprawne przypisanie:

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

Zważywszy jeśli owinąć i/lub operacje w zamknięciu lub po prostu przypisać je do pośredniej zmiennej logicznej, tracisz pogmatwanego komunikat o błędzie i jest przedstawiona z rzeczywistego błędu.

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

Teraz dlaczego dostaniemy ten mylący błąd. Oba operatory logiczne && i || są realizowane z warunkowym oceny ich odpowiednich wyrażeń stronie (rhs), tak że rhs można leniwie oceniana tylko w przypadku, gdy po lewej stronie (lhs) ocenia się true/false dla &&/|| operatorów , odpowiednio.

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

Ponieważ sama lhs jest nieprawidłowy dla zadania, które następuje, ewentualnie leniwy zamknięcie rhs zgłasza błąd poniesionych przez „zewnętrzne” Nieprawidłowe przypisanie z Bool typu do (), ale błąd rzucony („Binary op "&&" nie można zastosować ... ") nie jest faktycznym źródłem niepowodzenia połączenia &&.

Aby sprawdzić, możemy realizować nasze własne non-leniwy i operator, powiedzmy &&& i, zgodnie z oczekiwaniami, nie otrzymamy ten sam błąd zaciemniać:

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

Ta odpowiedź powinna zostać przyjęta.Ten komunikat o błędzie wprowadza w błąd w 'Swift 2', miejmy nadzieję, że zostanie on rozwiązany w przyszłej wersji, podobnie jak wcześniej błędy związane z blokowaniem. –

+3

Wciąż taki sam w Swift 3 –

2

podczas gdy drugi ma kilka naprawdę odpowiedź interesujące punkty, w tym konkretnym przypadku dodanie typu powrotu do funkcji rozwiązuje go.

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 
} 

byłby to powrót true jeśli a były prawdziwe, a jeśli nie, to będzie wyglądać na b (ocena leniwy).

Powiązane problemy