Sự khác biệt giữa Hồi giáo và Dòng và && trong Ruby?


Câu trả lời:


349

andlà giống như &&nhưng với quyền ưu tiên thấp hơn . Cả hai đều sử dụng đánh giá ngắn mạch .

CẢNH BÁO: andthậm chí có mức độ ưu tiên thấp hơn mức =bạn thường muốn tránh and. Có andthể tìm thấy một ví dụ khi sử dụng trong Hướng dẫn Rails trong phần " Tránh lỗi kết xuất kép ".


50
Sẽ là một ý tưởng tốt để chỉ định rằng người ta thường nên sử dụng &&, trong khi andchỉ nên sử dụng cho các trường hợp rất cụ thể.
Marc-André Lafortune

10
Một lời giải thích tốt khác ở đây: devblog.avdi.org/2010/08/02/USE-and-and-or-in-ruby .
Andrew Marshall

17
Từ liên kết của Andrew Marshall: "Một cách suy nghĩ khác andlà một ifcông cụ sửa đổi câu lệnh đảo ngược : next if widget = widgets.poptrở thành widget = widgets.pop and next. Đó là một cách tuyệt vời để đặt nó, thực sự khiến nó" nhấp "trong đầu tôi. (Và orgiống như một công cụ unlesssửa đổi đảo ngược .)
GMA

1
Kết hợp câu trả lời này với các chi tiết về câu trả lời của tadman và bạn sẽ có được toàn bộ bức tranh.
sargas

5
Avdi đã cập nhật thời gian sử dụng và so với &&. Về cơ bản sử dụng 'và' và 'hoặc' cho luồng điều khiển vì mức độ ưu tiên thấp hơn của chúng. devblog.avdi.org/2014/08/26/ cường
EricC

238

Sự khác biệt thực tế là sức mạnh ràng buộc, có thể dẫn đến hành vi kỳ dị nếu bạn không chuẩn bị cho nó:

foo = :foo
bar = nil

a = foo and bar
# => nil
a
# => :foo

a = foo && bar
# => nil
a
# => nil

a = (foo and bar)
# => nil
a
# => nil

(a = foo) && bar
# => nil
a
# => :foo

Điều tương tự làm việc cho ||or.


2
a = foo and bar (a = foo ) && bar chứng minh rằng andcó ưu tiên thấp hơn &&.
sargas

tôi không hiểu: "foo and bar" nghĩa là gì để trở về?
BKSpurgeon

a = foo and bartương đương với (a = :foo) and nil. Vì phép gán trả về giá trị logic ( :foo) nên phần thứ hai sẽ đánh giá, không thành công, trả về nil.
tadman

61

Các của Ruby Style Guide nói nó tốt hơn tôi có thể:

Sử dụng && / || cho các biểu thức boolean và / hoặc cho luồng điều khiển. (Quy tắc ngón tay cái: Nếu bạn phải sử dụng dấu ngoặc đơn bên ngoài, bạn đang sử dụng các toán tử sai.)

# boolean expression
if some_condition && some_other_condition
  do_something
end

# control flow
document.saved? or document.save!

53
Trên thực tế, hướng dẫn bây giờ nói để tránh and/ orhoàn toàn, và họ có thể có một điểm. Thường thì việc sử dụng chúng trong luồng điều khiển có thể được viết rõ ràng hơn bằng if/ unlesstoán tử (ví dụ document.save! unless document.saved?)
Yarin

@akostadinov trong trường hợp bạn không trolling: hướng dẫn về Phong cách Ruby không được viết bởi những người tạo ra Ruby. Ruby được tạo ra bởi Yukihiro Matsumoto và những người khác, trong khi Hướng dẫn về Phong cách Ruby chủ yếu là của Bozhidar Batsov.
Andrew Grimm

2
@AndrewGrimm, cảm ơn, tốt để biết. Xin lỗi vì đã troll nhưng tôi thực sự bối rối với một số khía cạnh của thực tế ruby. Một điều chắc chắn - mọi dự án ruby ​​đều cần các chính sách phong cách nghiêm ngặt để duy trì codebase.
akostadinov 04

37

||&&liên kết với quyền ưu tiên mà bạn mong đợi từ các toán tử boolean trong các ngôn ngữ lập trình ( &&rất mạnh, ||hơi kém mạnh).

andorcó quyền ưu tiên thấp hơn.

Ví dụ, không giống như ||, orcó quyền ưu tiên thấp hơn =:

> a = false || true
 => true 
> a
 => true 
> a = false or true
 => true 
> a
 => false

Tương tự như vậy, không giống như &&, andcũng có quyền ưu tiên thấp hơn =:

> a = true && false
 => false 
> a
 => false 
> a = true and false
 => false 
> a
 => true 

Hơn thế nữa, không giống như &&||, andorràng buộc với ưu tiên bằng nhau:

> !puts(1) || !puts(2) && !puts(3)
1
 => true
> !puts(1) or !puts(2) and !puts(3)
1
3
 => true 
> !puts(1) or (!puts(2) and !puts(3))
1
 => true

Liên kết yếu andorcó thể hữu ích cho các mục đích kiểm soát luồng: xem http://devblog.avdi.org/2010/08/02/USE-and-and-or-in-ruby/ .


2
"Không giống như ||, orcó quyền ưu tiên thấp hơn =" ... bây giờ nó có ý nghĩa hơn, cảm ơn!
Steph Sharp

18

andcó quyền ưu tiên thấp hơn &&.

Nhưng đối với một người dùng không thông thạo, các sự cố có thể xảy ra nếu nó được sử dụng cùng với các toán tử khác có quyền ưu tiên nằm ở giữa, ví dụ, toán tử gán:

def happy?() true; end
def know_it?() true; end

todo = happy? && know_it? ? "Clap your hands" : "Do Nothing"

todo
# => "Clap your hands"

todo = happy? and know_it? ? "Clap your hands" : "Do Nothing"

todo
# => true

1
Cảm ơn bạn, nhưng mức độ ưu tiên của "và" khác với "&&" như thế nào?
BKSpurgeon

2
@BKSpurgeon Xem tại đây để biết danh sách ưu tiên của nhà điều hành trong Ruby.
thutt

5

andcó mức độ ưu tiên thấp hơn, chủ yếu chúng tôi sử dụng nó như một công cụ sửa đổi dòng điều khiển, chẳng hạn như if:

next if widget = widgets.pop

trở thành

widget = widgets.pop and next

Dành cho or:

raise "Not ready!" unless ready_to_rock?

trở thành

ready_to_rock? or raise "Not ready!"

Tôi thích sử dụng ifnhưng không and, vì ifdễ hiểu hơn, vì vậy tôi chỉ cần bỏ qua andor.

Tham khảo " Sử dụng các ứng dụng khác và trên mạng và trong hoặc trên Ruby " để biết thêm thông tin.


0

Tôi không biết đây là ý định của Ruby hay đây là lỗi nhưng hãy thử mã này bên dưới. Mã này được chạy trên phiên bản Ruby 2.5.1 và trên hệ thống Linux.

puts 1 > -1 and 257 < 256
# => false

puts 1 > -1 && 257 < 256
# => true

1
@JakubArnold Sarcasm không bao giờ hữu ích. Ví dụ đôi khi là.
BobRodes

@BobRodes Đó không phải là một sự mỉa mai. Có 7 câu trả lời, 6 trong số đó đã có ví dụ.
Jakub Arnold

1
@JakubArnold Tôi vẫn thấy ví dụ này hữu ích.
BobRodes

Tôi cũng nhận được kết quả kỳ lạ. v1 = true và false p v1 # => app.rb: true, IRB: false v2 = true && false p v2 # => app.rb: false, IRB: false đặt 1> -1 && 257 <256 # => app.rb: false, IRB: false
Rich_F
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.