Không | có nghĩa là gì? (nhà điều hành ống bằng nhau)


249

Tôi đã thử tìm kiếm bằng Google Search và Stack Overflow, nhưng nó không hiển thị bất kỳ kết quả nào. Tôi đã thấy điều này trong mã thư viện mã nguồn mở:

Notification notification = new Notification(icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;

"| =" ( pipe equal operator) Có nghĩa là gì?


4
Tôi tự hỏi nếu thêm một cái gì đó như pipe equal operatorcâu hỏi này hoặc bất kỳ tài liệu nào khác về chủ đề này sẽ không giúp mọi người tìm kiếm.
Denys Séguret

10
@EJP là các bạn đang nói về tài liệu này . Nó rõ ràng nói với các tài liệu thiếu tài liệu về việc sử dụng này.
wtsang02

36
Trừ khi bạn biết nó được gọi là ống bằng nhau, thực sự rất khó để tìm kiếm mà không hỏi ai.
ataulm

@ataulm thực sự, đã dành một chút thời gian để tìm ra một thuật ngữ vertical barmà cuối cùng đã dẫn tôi đến đây.
hủy hoại

1
Bản sao có thể có của toán tử | = làm gì trong Java?
pored91

Câu trả lời:


323

|=đọc theo cùng một cách như +=.

notification.defaults |= Notification.DEFAULT_SOUND;

giống như

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

nơi |là bit-wise toán tử OR.

Tất cả các nhà khai thác được tham khảo ở đây .

Một toán tử bit khôn ngoan được sử dụng bởi vì, thông thường, các hằng số đó cho phép một int mang cờ.

Nếu bạn nhìn vào các hằng số đó, bạn sẽ thấy rằng chúng có sức mạnh của hai:

public static final int DEFAULT_SOUND = 1;
public static final int DEFAULT_VIBRATE = 2; // is the same than 1<<1 or 10 in binary
public static final int DEFAULT_LIGHTS = 4; // is the same than 1<<2 or 100 in binary

Vì vậy, bạn có thể sử dụng bit-khôn ngoan HOẶC để thêm cờ

int myFlags = DEFAULT_SOUND | DEFAULT_VIBRATE; // same as 001 | 010, producing 011

vì thế

myFlags |= DEFAULT_LIGHTS;

đơn giản có nghĩa là chúng ta thêm một lá cờ.

Và đối xứng, chúng tôi kiểm tra một cờ được thiết lập bằng cách sử dụng &:

boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;

2
Cũng giống như j += 1;là giống như j = j + 1;.
David Schwartz

1
@ARS: Tôi không thể nghĩ ra một ví dụ ngược trong Java (có thể nếu jvolatile?), Nhưng tôi sẽ tin bạn.
David Schwartz

6
@DavidSchwartz Xem cái này
arshajii

2
boolean hasVibrate = DEFAULT_VIBRATE & myFlags;- bạn có thể dịch từ intsang booleannhư thế trong Java không? Điều đó sẽ hợp lệ trong C, nhưng tôi nghĩ trong Java nó phải được viết làboolean hasVibrate = ((DEFAULT_VIBRATE & myFlags) == DEFAULT_VIBRATE);
BlueRaja - Danny Pflughoeft

1
@DavidSchwartz Wow, sự so sánh đó +=cuối cùng đã giúp tôi hiểu được nó. Cảm ơn!
C4d

39

Bạn đã có đủ câu trả lời cho câu hỏi của bạn. Nhưng có thể câu trả lời của tôi giúp bạn nhiều hơn về |=loại toán tử nhị phân.

Tôi đang viết bảng cho các toán tử bitwise :
Sau đây là hợp lệ:

----------------------------------------------------------------------------------------
Operator   Description                                   Example
----------------------------------------------------------------------------------------
|=        bitwise inclusive OR and assignment operator   C |= 2 is same as C = C | 2
^=        bitwise exclusive OR and assignment operator   C ^= 2 is same as C = C ^ 2
&=        Bitwise AND assignment operator                C &= 2 is same as C = C & 2
<<=       Left shift AND assignment operator             C <<= 2 is same as C = C << 2
>>=       Right shift AND assignment operator            C >>= 2 is same as C = C >> 2  
----------------------------------------------------------------------------------------

lưu ý tất cả các toán tử là toán tử nhị phân.

Cũng lưu ý: (đối với các điểm dưới đây tôi muốn thêm câu trả lời của mình)

  • >>>là toán tử bitwise trong Java được gọi là shift Unsign
    nhưng >>>=không phải là một toán tử trong Java. >>> = tổng đài

  • ~là bit bổ sung bitwise, 0 to 1 and 1 to 0(toán tử Unary) nhưng ~=không phải là toán tử.

  • Ngoài ra, !được gọi là Toán tử KHÔNG logic, nhưng !=Kiểm tra xem giá trị của hai toán hạng có bằng nhau hay không, nếu các giá trị không bằng nhau thì điều kiện trở thành đúng. ví dụ (A != B) is true. nơi như A=!Bphương tiện nếu Bđược truethì Atrở thành false(và nếu Bfalsesau đó Atrở thành true).

lưu ý phụ: |không được gọi là đường ống, thay vào đó gọi là đường ống OR, đường ống là thuật ngữ hệ vỏ chuyển một quá trình ra tiếp theo ..


9
Tôi có ấn tượng rằng "pipe" là tên của nhân vật, đó là nơi mà thuật ngữ vỏ xuất phát. Nhưng, nhìn vào Wikipedia, nó thực sự được gọi là "thanh dọc" và "ống" dành riêng cho các lệnh shell. Chỉ muốn nói cảm ơn vì đã thêm ghi chú bên đó!
Caleb Brinkman

18

Tôi đang tìm kiếm một câu trả lời về những gì |=trong Groovy và mặc dù các câu trả lời ở trên là đúng nhưng chúng không giúp tôi hiểu được một đoạn mã cụ thể mà tôi đang xem.

Cụ thể, khi được áp dụng cho biến boolean "| =" sẽ đặt nó thành TRUE lần đầu tiên nó gặp biểu thức trung thực ở phía bên phải và sẽ GIỮ giá trị TRUE của nó cho tất cả các cuộc gọi tiếp theo. Giống như một cái chốt.

Dưới đây là một ví dụ đơn giản về điều này:

groovy> boolean result  
groovy> //------------ 
groovy> println result           //<-- False by default
groovy> println result |= false 
groovy> println result |= true   //<-- set to True and latched on to it
groovy> println result |= false 

Đầu ra:

false
false
true
true

Chỉnh sửa : Tại sao điều này hữu ích?

Xem xét một tình huống mà bạn muốn biết nếu có bất cứ điều gì thay đổi trên nhiều đối tượng và nếu có thì thông báo cho một trong những thay đổi. Vì vậy, bạn sẽ thiết lập một hasChangesboolean và đặt nó |= diff (a,b)và sau đó |= dif(b,c)vv Đây là một ví dụ ngắn gọn:

groovy> boolean hasChanges, a, b, c, d 
groovy> diff = {x,y -> x!=y}  
groovy> hasChanges |= diff(a,b) 
groovy> hasChanges |= diff(b,c) 
groovy> hasChanges |= diff(true,false) 
groovy> hasChanges |= diff(c,d) 
groovy> hasChanges 

Result: true

10
Đúng, cùng giữ trong Java. Nhưng điều đáng chú ý là hoạt động OR như vậy không phảiy|=exprngắn mạch (không giống như y = y || expr), có nghĩa là exprluôn luôn được đánh giá. Đây không phải là rõ ràng đối với tôi lần đầu tiên :) Vì vậy, điều quan trọng cần lưu ý trước khi refactoring mà thay thế là y|=expry=y||xkhông ngữ nghĩa tương đương trong trường hợp exprthực sự có tác dụng phụ.
NIA

1
Và, có này trong tâm trí, trong trường hợp của bạn với hasChangesnó sẽ có thể được tốt hơn để thích y=y||xhình thức để được hưởng lợi từ ngắn ciruit, bởi vì khi bạn tìm thấy bất kỳ sự thay đổi đó là không thực sự cần thiết để làm diffs susequent vì bạn đã biết câu trả lời. (Đặc biệt quan trọng trong tình huống thực tế khi so sánh các đối tượng rất phức tạp và việc xử difflý chúng không hoàn toàn nhanh)
NIA

@NIA Cảm ơn bạn đã bỏ phiếu. Có, tôi đồng ý với quan điểm của bạn về ngắn mạch.
dbrin

2
@FranklinYu tất nhiên không thực hiện chi tiết. Không ngắn mạch không được đề cập cụ thể tại địa điểm bạn đã tham chiếu chỉ vì nó không phải là đặc thù - đó là hành vi mặc định và bình thường đối với hầu hết các nhà khai thác. Tính đặc thù thực sự là tính lưu hành ngắn ||&&, và trong các phần tương ứng 15,2315,24 của đặc điểm kỹ thuật này thực tế được tuyên bố rõ ràng, và sự khác biệt này |&được nhấn mạnh.
NIA

2
@FranklinYu Vì vậy, tôi nghĩ rằng không cần phải nói gì về điều này một lần nữa bên dưới trong phần bạn đã tham chiếu (15,26.2 "Toán tử gán bù") chỉ vì các phép gán compond đơn giản là luôn không ngắn mạch (không có ||=&&=toán tử sẽ phá vỡ quy tắc và yêu cầu đề cập đặc biệt).
NIA

13

Đó là một rút ngắn cho điều này:

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

|là một chút khôn ngoan HOẶC.



3

Lưu ý: || = không tồn tại. (logic hoặc) Bạn có thể sử dụng

y= y || expr; // expr is NOT evaluated if y==true

hoặc là

y = expr ? true : y;  // expr is always evaluated.

4
Chưa hoàn chỉnh: bạn vẫn có thể sử dụng y |= exprvới booleans và nó cho kết quả tương tự ynhư các biến thể của bạn với lưu ý quan trọng rằng nó không phải là curtuit ngắn , có nghĩa là expr luôn được đánh giá, ngay cả trong trường hợpy==true
NIA
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.