2010-10-22 25 views
74

thể trùng lặp:
What does !! mean in ruby?Ruby, !! điều hành (a/k/A đôi-bang)

Hi,

Tôi mới đến Ruby và không thể tìm thấy ở bất cứ đâu mô tả về những gì "!!" có nghĩa.

Dưới đây là một ví dụ:

def signed_in? 
    !!current_user 
end 

Nếu đây là một đôi tiêu cực, tại sao không nói:

def signed_in? 
    current_user 
end 

Xin vui lòng giúp.

+0

Bạn có nhìn vào các câu hỏi đã được trao cho bạn sau khi bạn đã nhập tiêu đề câu hỏi của bạn không? – Nakilon

+4

Vâng, không có gì ở đó cả. Tôi thực sự đã tìm thấy câu hỏi tương tự giải thích cho tôi câu hỏi thứ hai, nhưng tôi phải tìm kiếm bằng "cú đúp" không rõ ràng như bạn nghĩ. – Vitaly

+3

Vâng, thuật toán câu hỏi tương tự bị lừa dễ dàng khi các phần quan trọng của tiêu đề là các ký tự dấu chấm câu. – pkaeding

Trả lời

98

Trong hầu hết các ngôn ngữ lập trình, bao gồm Ruby, ! sẽ trả về giá trị boolean của toán hạng. Vì vậy, khi bạn chuỗi hai dấu chấm than với nhau, nó chuyển đổi giá trị thành boolean.

121

Trong Ruby (và nhiều ngôn ngữ khác) có nhiều giá trị đánh giá thành true trong ngữ cảnh boolean và một số ít sẽ đánh giá sai. Trong Ruby, the only two things that evaluate to false are false (itself) and nil.

Nếu bạn phủ nhận điều gì đó, điều đó sẽ buộc một ngữ cảnh boolean. Tất nhiên, nó cũng phủ nhận nó. Nếu bạn bỏ qua nó, nó sẽ ép buộc ngữ cảnh boolean, nhưng trả về giá trị boolean thích hợp.

Ví dụ:

"hello" #-> this is a string; it is not in a boolean context 
!"hello" #-> this is a string that is forced into a boolean 
      # context (true), and then negated (false) 
!!"hello" #-> this is a string that is forced into a boolean 
      # context (true), and then negated (false), and then 
      # negated again (true) 
!!nil  #-> this is a false-y value that is forced into a boolean 
      # context (false), and then negated (true), and then 
      # negated again (false) 

Trong ví dụ của bạn, signed_in? phương pháp phải trả lại một giá trị boolean (như được chỉ ra theo quy ước của các nhân vật ?). Logic nội bộ mà nó sử dụng để quyết định giá trị này bằng cách kiểm tra xem biến current_user có được đặt hay không. Nếu được đặt, nó sẽ đánh giá thành true trong ngữ cảnh boolean. Nếu không, nó sẽ đánh giá là sai. Phép phủ định kép buộc giá trị trả về là boolean.

+0

vì vậy! "" Có hiệu lực là ** true ** và !! "" thành ** false ** hoặc là chuỗi rỗng có đúng không? – berto77

+1

'!" "' Là 'sai', bởi vì các giá trị false-y chỉ là' false' và 'nil'. Mọi thứ khác là sự thật-y: http://phrogz.net/ProgrammingRuby/language.html#truthvalues ​​Tôi đã chỉnh sửa câu trả lời của mình để làm cho điều này rõ ràng hơn. – pkaeding

+2

Đây là câu trả lời tốt hơn vì nó giải thích TẠI SAO. Có vẻ như cùng một loại hack bạn thấy trong Java đôi khi chuyển đổi một int thành một String bằng cách gắn thêm một "" vào nó (theo cách mà tôi KHÔNG ủng hộ - tôi tin rằng đây là thực hành không tốt trong Java). Cho rằng đây là thực hành không tốt trong Java, tôi không hiểu tại sao các ngôn ngữ như Ruby đang sử dụng nó. Mọi thứ có thể sử dụng ít nhất số ký tự có thể? –

27

!! chỉ là ! (toán tử phủ định boolean) được viết hai lần. Nó sẽ phủ nhận đối số, sau đó phủ nhận phủ định. Nó hữu ích bởi vì bạn có thể sử dụng nó để có được một boolean từ bất kỳ giá trị nào. ! đầu tiên sẽ chuyển đổi đối số thành boolean, ví dụ: true nếu đó là nil hoặc falsefalse nếu không. Thứ hai sẽ phủ nhận điều đó một lần nữa để bạn nhận được giá trị boolean của đối số, false cho nil hoặc false, true cho mọi thứ khác.

Trong Ruby, bạn có thể sử dụng bất kỳ giá trị nào trong câu lệnh if, ví dụ: if current_user sẽ thực thi nếu người dùng hiện tại không phải là nil. Hầu hết thời gian này là tuyệt vời vì nó giúp chúng tôi nhập các thử nghiệm rõ ràng (như if !current_user.nil?, dài hơn ít nhất sáu ký tự). Nhưng đôi khi nó có thể thực sự khó hiểu nếu bạn trả về một đối tượng khi phương thức ngụ ý rằng nó trả về một boolean. Các phương thức có tên kết thúc bằng ? sẽ trả lại giá trị trung thực hoặc sai lệch, tức là chúng trả về thứ gì đó sẽ đánh giá là true hoặc false. Tuy nhiên, nó có thể thực sự lộn xộn nếu signed_in? trả về một đối tượng người dùng.Ví dụ: nếu bạn đang cố gắng gỡ lỗi vì sao một số mã sử dụng signed_in? không hoạt động, có thể bạn sẽ rất bối rối khi đối tượng người dùng bật lên nơi bạn mong đợi true hoặc false. Trong trường hợp đó, bạn nên thêm !! trước số return vì điều đó đảm bảo rằng giá trị trung thực hoặc sai sẽ được trả lại dưới dạng true hoặc false.

3

Khi bạn hiểu chính xác đó là việc sử dụng tiêu cực kép của toán tử !. Điều đó nói rằng, trong khi nó có thể là một cách viết tắt để kiểm tra xem một biến có thể là không hoặc không, IMO đó là quá ngắn gọn. Hãy xem thisthis bài đăng. Lưu ý rằng trong Ruby, kiểm tra một cái gì đó để nil sẽ đánh giá sai.

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