2016-01-23 27 views
21

Rõ ràng là phải có cách AND hoặc OR nhiều boolean.Lỗi Swift: Toán tử nhị phân '&&' không thể áp dụng cho hai toán hạng 'Bool'

Tôi nhận được lỗi này cố gắng để viết một hàm như thế này ...

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 
} 

các giải pháp này là gì?

+9

Bạn đang thiếu kiểu trả về '... -> Bool' trong chữ ký hàm của bạn. (Lỗi này có phần gây hiểu lầm: nhưng không có kiểu trả về được chỉ định, hàm mong đợi kiểu trả về '()' (tuple trống), trong khi bạn trả về một boolean). – dfri

Trả lời

51

Lỗi này là sai lầm: cốt lõi là bạn đang bỏ lỡ sự trở lại loại ... -> Bool trong chữ ký chức năng của bạn, vì thế cố gắng gán một giá trị boolean để trống loại tuple () (không có kiểu trả về rõ ràng, chức năng hy vọng trả về là loại tuple rỗng ()).

Bạn có thể tạo lại lỗi gây hiểu lầm này cho bất kỳ nỗ lực nào để gán giá trị boolean cho loại không logic, trong đó giá trị boolean là kết quả của biểu thức logic AND/OR được thực hiện trong cùng một biểu thức như gán không hợp lệ:

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

trong khi nếu bạn quấn hoạt động của bạn và/hoặc đóng cửa hoặc đơn giản là giao cho một biến boolean trung gian, bạn mất thông báo lỗi khó hiểu và được trình bày với các lỗi thực tế.

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

Bây giờ là tại sao bạn đang đưa ra lỗi sai lệch này. Cả hai toán tử logic &&|| được thực hiện với một đánh giá điều kiện của biểu thức bên tay phải của họ (rhs), do đó rhs thể uể oải đánh giá chỉ trong trường hợp phía bên tay trái (lhs) để đánh giá true/false cho &&/|| nhà khai thác , tương ứng.

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

Kể từ khi lhs chính nó là không hợp lệ cho việc giao nhận sau đây, có thể đóng cửa lười biếng rhs ném một lỗi phát sinh do việc chuyển nhượng không hợp lệ "bên ngoài" từ Bool loại để (), nhưng lỗi ném ("Binary op Không thể áp dụng '&&' ... ") không phải là nguồn thực sự của sự thất bại của cuộc gọi &&.

Để xác minh, chúng tôi có thể thực hiện riêng của chúng tôi không lười biếng và nhà điều hành, nói &&&, và, như mong đợi, chúng tôi không nhận được lỗi xáo trộn cùng:

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

Câu trả lời này phải được chấp nhận.Thông báo lỗi này gây hiểu lầm trong 'Swift 2', hy vọng nó sẽ được sửa trong phiên bản tương lai, giống như các lỗi liên quan đến lỗi gây hiểu lầm trước đây. –

+3

Vẫn như cũ trong Swift 3 –

2

Trong khi câu trả lời khác có một số thực sự điểm thú vị, trong trường hợp cụ thể này, việc thêm một kiểu trả về cho hàm của bạn sẽ giải quyết nó.

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 
} 

này sẽ quay trở lại true nếu a là đúng, và nếu không, nó sẽ xem xét để b (đánh giá lười biếng).

Các vấn đề liên quan