2011-07-12 27 views
14

Tôi đang xem xét các khác biệt được gửi cho một dự án của một nhà phát triển khác, và họ có rất nhiều mã mà không !!<some BOOL value>. Trong thực tế, điều này có vẻ là mô hình tiêu chuẩn của họ để thực hiện boolean getters và setters. Họ đã triển khai mã của họ như:Mục tiêu-C - Có !! BOOL Beneficial

- (BOOL) hasId { 
    return !!hasId_; 
} 
- (void) setHasId:(BOOL) value { 
    hasId_ = !!value; 
} 

Tôi chưa bao giờ thấy mẫu này trước đây và tôi tự hỏi liệu có lợi ích gì khi sử dụng nó hay không. Sự phủ định kép có làm ích gì không?

+0

lần duy nhất tôi thấy là một lớp không phải là cách đơn giản để chuyển sang bool, vì vậy họ không thể làm 'if (myInstance)', nhưng nó đã làm quá tải toán tử '!' , vì vậy họ sẽ làm 'if (!! myInstance)'. Nhưng trong trường hợp của bạn, tôi không có ý tưởng. – filipe

Trả lời

13

Nhà điều hành boolean đôi chỉ làm cho chắc chắn rằng giá trị trả về là 1 hoặc 0. Đó là tất cả:)

+5

… ngăn chặn mã như 'obj.hasId = 42; if (obj.hasId == YES) 'từ thất bại điều kiện. Về mặt kỹ thuật 'YES' là (hiện tại) được ánh xạ tới 1 vì vậy các giá trị số nguyên là khác nhau. Tuy nhiên, về mặt khái niệm, cả 42 và 'YES' đại diện cho một giá trị boolean thực sự. Phép phủ định kép thu hẹp 42 phép gán thành một phép gán 'YES'. –

+0

Cảm ơn, tôi cho rằng nó có lẽ là một cái gì đó như thế. Nhưng nó có hữu ích để làm điều đó theo cách đó/là bất kỳ lỗi tiềm năng nào tránh được không?Giống như có lẽ điều này ngăn chặn một lỗi không mong muốn khi thực hiện so sánh dưới dạng 'if (obj.hasId == YES)'? Mặc dù không phải là một so sánh trong phong cách nghèo anyways? Edit: nevermind, Bavarious đánh tôi với nó. – aroth

+0

Đúng, nhưng đôi khi thực sự hữu ích, để chuyển đổi thành 1 hoặc 0, giống như SQLite chỉ lưu các trường boolean chỉ bằng 1 hoặc 0. –

3

! là một nhà điều hành phủ định logic. Vì vậy, nếu setHasId: đã được thông qua, ví dụ, 0x2 thì phủ định kép sẽ lưu trữ 0x1.

1

Nó tương đương với:

hasId_ = value ? 1 : 0; 

Nó rất hữu ích trong một số trường hợp bởi vì nếu bạn làm điều này:

BOOL x = y & MY_FLAG; 

Bạn có thể nhận được 0 nếu MY_FLAG được thiết lập, bởi vì kết quả được cắt ngắn để kích thước của BOOL (8 bit). Điều này là bất ngờ. Vì lý do tương tự, đôi khi mọi người thích rằng BOOL là 0 hoặc 1 (do đó hoạt động bit hoạt động như mong đợi). Nó thường là không cần thiết.

Trong các ngôn ngữ có sẵn một loại bool như C (C99) và C++, chuyển đổi số nguyên thành bool thực hiện điều này tự động.

0

Nó có ý nghĩa hơn trong một số trường hợp khác ví dụ như nơi bạn đang trở BOOL nhưng không muốn đưa một tuyên bố if trong.

- (BOOL)isMyVarSet 
{ 
    return !!myVar; 
} 

Trong trường hợp này tôi không thể chỉ trở myVar vì nó không phải là BOOL (đây là một ví dụ rất giả tạo - tôi không thể đào một ví dụ phong nha từ các dự án của tôi).

0

Tôi đã sử dụng này trước và tôi tin rằng:

if (!!myVar)

tương đương với:

if (myVar != nil)

Về cơ bản, tôi sử dụng nó để xác minh giá trị của SOMETHING.

Tôi sẽ thừa nhận ... đây có lẽ không phải là phương pháp hay nhất hoặc được hiểu nhiều nhất để đạt được mục tiêu này.

+0

Sự khác biệt là: (myVar! = Nil) là khá rõ ràng, trong khi (!! myVar) dừng bạn trong bài hát của bạn, bạn phải suy nghĩ chăm chỉ những gì nó làm, và sau đó bạn phải suy nghĩ thậm chí còn khó hơn tìm hiểu xem ai đã viết nó thực sự có nghĩa là nó. Tốt nhất để thể hiện rõ ý bạn là gì. – gnasher729

+0

Hoàn toàn đồng ý! Câu trả lời của tôi là 3 tuổi, và tôi TUYỆT ĐỐI sẽ không viết !! var trong bất kỳ mã mới ngày hôm nay! – mbm29414

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