2008-10-02 41 views
135

Cá nhân tôi thích nhà cung cấp độc quyền hoặc, ^ khi điều này có ý nghĩa trong ngữ cảnh kiểm tra boolean do tính đồng nhất của nó. Tôi rất thích viếtCó thực hành tốt để sử dụng toán tử xor để kiểm tra boolean không?

if (boolean1^boolean2) 
{ 
    //do it 
} 

hơn

if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
    //do it 
} 

nhưng tôi thường nhận được vẻ bối rối từ các nhà phát triển Java có kinh nghiệm khác (không chỉ là người mới), và đôi khi bình luận về làm thế nào nó chỉ nên được sử dụng cho Bitwise hoạt động.

Tôi rất tò mò về các phương pháp hay nhất liên quan đến việc sử dụng toán tử ^.

Trả lời

272

Thay vào đó, bạn chỉ cần sử dụng !=.

+34

*" Có gì sai với! = "*' Bool1^^ bool2 bool3' làm cho tinh thần hợp lý hơn đối với tôi hơn 'bool1! = Bool2! = Bool3' –

+3

não của tôi đau. Vì vậy, có thể! = cho kết quả không chính xác hay không? – vemv

+24

@vemv, '! =' cho kết quả chính xác cho 'boolean' (nhưng không phải cho 'Boolean' vì vậy hãy cẩn thận). Không phải lúc nào cũng khá, ví dụ '(một số! = null! = (khác! = null) 'không phải là rất dễ đọc.Bạn có thể trích xuất các phần trong boolean rõ ràng, hoặc giải nén'! = 'trong một phương thức riêng biệt. – ivant

12

Tôi nghĩ sẽ ổn nếu bạn đã nhận xét, ví dụ: //^== XOR.

-1

Nếu mẫu sử dụng biện minh cho nó, tại sao không? Trong khi nhóm của bạn không nhận ra người điều hành ngay lập tức, với thời gian họ có thể. Con người học từ mới mọi lúc. Tại sao không trong lập trình?

Cảnh báo duy nhất tôi có thể nêu rõ là "^" không có ngữ nghĩa ngắn mạch của kiểm tra boolean thứ hai của bạn. Nếu bạn thực sự cần ngữ nghĩa ngắn mạch, thì phương thức static util cũng hoạt động.

public static boolean xor(boolean a, boolean b) { 
    return (a && !b) || (b && !a); 
} 
+16

Tôi không thấy bất kỳ mạch ngắn nào có thể với xor - bạn phải biết cả hai a và b để đánh giá kết quả. – Thelema

+7

Ngoài ra, các đối số sẽ được đánh giá att thời gian gọi, vì vậy không có ngắn mạch sẽ xảy ra bất cứ điều gì. – erikkallen

+3

Ngoài ra, xor phải là một thao tác đơn ở mức máy. –

26

Tôi nghĩ bạn đã trả lời câu hỏi của riêng mình - nếu bạn có ngoại hình lạ từ mọi người, có thể an toàn hơn khi sử dụng tùy chọn rõ ràng hơn.

Nếu bạn cần nhận xét, thì có thể bạn nên thay thế bằng phiên bản tiết kiệm hơn và không khiến mọi người đặt câu hỏi ngay từ đầu.

+2

Tôi có thể khẳng định bạn, bạn sẽ có ngoại hình lạ lùng từ tôi, khi bạn nghiêm túc viết '(boolean1 &&! Boolean2) || (boolean2 &&! boolean1) 'trong một mã ứng dụng thực tế ... – Holger

6

Gần đây tôi đã sử dụng xor trong một dự án JavaScript tại nơi làm việc và kết thúc bằng việc thêm 7 dòng nhận xét để giải thích những gì đang diễn ra. Lý do cho việc sử dụng xor trong ngữ cảnh đó là một trong các điều khoản (term1 trong ví dụ bên dưới) có thể không phải là hai mà là ba giá trị: undefined, true hoặc false trong khi khác (term2) có thể là true hoặc false. Tôi sẽ phải thêm một kiểm tra bổ sung cho undefined trường hợp nhưng với xor, sau đây là đủ kể từ khi xor buộc hạn đầu tiên được đầu tiên đánh giá là một Boolean, cho phép undefined được coi là false:

if (term1^term2) { ... 

Đó là, cuối cùng, một chút của một overkill, nhưng tôi muốn giữ nó trong đó anyway, như một loại trứng Phục sinh.

16

Tôi thấy rằng tôi có nhiều cuộc trò chuyện tương tự. Một mặt, bạn có một phương pháp nhỏ gọn, hiệu quả để đạt được mục tiêu của mình. Mặt khác, bạn có cái gì đó mà phần còn lại của nhóm của bạn có thể không hiểu, làm cho nó khó để duy trì trong tương lai.

Quy tắc chung của tôi là hỏi xem kỹ thuật được sử dụng có phải là điều hợp lý để mong đợi các lập trình viên nói chung biết hay không. Trong trường hợp này, tôi nghĩ rằng nó là hợp lý để mong đợi các lập trình viên để biết làm thế nào để sử dụng các toán tử boolean, vì vậy sử dụng xor trong một câu lệnh if là okay.

Làm ví dụ về điều gì đó không ổn, hãy sử dụng xor để hoán đổi hai biến mà không sử dụng biến tạm thời. Đó là một mẹo mà tôi sẽ không mong đợi mọi người quen thuộc, vì vậy nó sẽ không vượt qua được việc xem xét mã.

-3

! = Là OK để so sánh hai biến. Nó không hoạt động, mặc dù, với nhiều so sánh.

3
if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
    //do it 
} 

IMHO mã này có thể được đơn giản hóa:

if(boolean1 != boolean2) 
{ 
    //do it 
} 
-3
str.contains("!=")^str.startsWith("not(") 

trông tốt hơn cho tôi hơn

str.contains("!=") != str.startsWith("not(") 
-3

Như một nhà điều hành Bitwise, xor là nhanh hơn nhiều so với bất kỳ phương tiện khác để thay thế nó. Vì vậy, để tính toán hiệu quả và khả năng mở rộng, xor là bắt buộc.

Ý kiến ​​cá nhân chủ quan của tôi: Tuyệt đối cấm, vì bất kỳ mục đích nào, để sử dụng bình đẳng (== hoặc! =) Cho các phép toán. Sử dụng nó cho thấy thiếu đạo đức lập trình cơ bản và nguyên tắc cơ bản. Bất cứ ai mang đến cho bạn bối rối nhìn qua^nên được gửi trở lại những điều cơ bản của đại số boolean (tôi đã bị cám dỗ để viết "để các con sông của niềm tin" ở đây :)).

+1

Ngoại trừ JIT là cực kỳ tốt ở keyhole (ít) tối ưu hóa, như thay thế một biểu thức boolean với nhau. –

+1

Ngoài ra,^không phải chủ yếu là toán tử Boolean (logic), nó là toán tử bitwise. Nó nói với người đọc để làm chậm, bởi vì có khả năng là lỗi đăng nhập. Nếu bạn sử dụng^for! =, Bạn sẽ bị rối tung lên nếu bạn từng lập trình trong C. Các toán tử bitwise là tín hiệu cho người đọc của bạn (những người gỡ lỗi mã của bạn, kể cả bạn) để làm chậm và tìm lỗi đăng nhập . Và chúng có thể phức tạp. Ví dụ, bạn có biết rằng% của Java không đúng modulo, như trong C hay Python? Tôi đã từng có một đoạn mã chạy giống nhau trong C, JavaScript và Python, nhưng không phải trong Java. –

+5

Làm thế nào điều này đã bao giờ được upvoted? Trước hết, trong Java XOR và! = Được biên dịch [http://stackoverflow.com/a/4175512/202504] (đối với cùng một mã chính xác), thứ hai ngay cả trong việc kiểm tra lắp ráp cho sự bình đẳng và xor là các hoạt động đơn giản từng cái. Bạn có bất kỳ số nào để sao lưu bản sao kê của mình không? – jmiserez

5

Với ý tưởng rõ ràng về mã, ý kiến ​​của tôi là sử dụng XOR trong kiểm tra boolean không phải là cách sử dụng điển hình cho toán tử bitwise XOR. Từ kinh nghiệm của tôi, Bitwise XOR trong Java là thường sử dụng để thực hiện một mặt nạ flag toggle hành vi:

flags = flags^MASK; 

This bài viết bởi Vipan Singla giải thích các trường hợp sử dụng nhiều chi tiết.

Nếu bạn cần sử dụng XOR bitwise như trong ví dụ của bạn, hãy nhận xét lý do bạn sử dụng nó, vì nó có thể yêu cầu ngay cả đối tượng biết đọc bit để dừng lại trong các bản nhạc của họ để hiểu lý do bạn sử dụng nó.

8

Bạn có thể luôn luôn chỉ cần quấn nó trong một chức năng để cung cấp cho nó một cái tên dài dòng:

public static boolean XOR(boolean A, boolean B) { 
    return A^B; 
} 

Nhưng, có vẻ như với tôi rằng nó sẽ không khó cho bất cứ ai không biết những gì^nhà điều hành cho Google nó thực sự nhanh chóng. Nó sẽ không khó nhớ sau lần đầu tiên. Kể từ khi bạn yêu cầu sử dụng khác, nó phổ biến để sử dụng XOR cho bit masking.

Bạn cũng có thể use XOR to swap the values in two variables without using a third temporary variable.

// Swap the values in A and B 
A ^= B; 
B ^= A; 
A ^= B; 

Đây là Stackoverflow question related to XOR swapping.

-1

Cá nhân tôi thích biểu thức "boolean1^boolean2" do tính ngắn gọn của nó.

Nếu tôi ở trong tình huống của bạn (làm việc trong một nhóm), tôi sẽ thỏa hiệp bằng cách đóng gói logic "boolean1^boolean2" trong một hàm có tên mô tả như "isDifferent (boolean1, boolean2)".

Ví dụ, thay vì sử dụng "boolean1^boolean2", bạn sẽ gọi là "isDifferent (boolean1, boolean2)" như vậy:

if (isDifferent(boolean1, boolean2)) 
{ 
    //do it 
} 

của bạn "isDifferent (boolean1, boolean2)" chức năng sẽ trông như thế :

private boolean isDifferent(boolean1, boolean2) 
{ 
    return boolean1^boolean2; 
} 

Tất nhiên, giải pháp này đòi hỏi việc sử dụng các cuộc gọi chức năng bề ngoài là không liên quan, mà tự nó là tùy thuộc vào Thực tiễn tốt nhất xem xét kỹ lưỡng, nhưng nó tránh được sự rườm rà (và xấu xí) khái niệm "(boolean1 & & boolean2!) | | (Boolean2 & &! Boolean1) "!

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