Yanıtlar:
Değil. Bir değeri bir boole değerine dönüştürmek için kullanılır:
!!nil #=> false
!!"abc" #=> true
!!false #=> false
Ruby için tek yanlış değerler olduğu için genellikle kullanmak gerekli değildir nilve falsebu nedenle konvansiyonun ayakta kalmasına izin vermek en iyisidir.
Bir düşünün
!(!some_val)
Meşru olarak kullanılan bir şey, büyük miktarda veri döndürülmesini önlemektir. Örneğin, has_image?yönteminizde muhtemelen 3 MB resim verisi döndürmek istemezsiniz veya yöntemdeki tüm kullanıcı nesnesini döndürmek istemeyebilirsiniz logged_in?. Kullanarak !!bu nesneleri basit true/ false.
.nil?kullanmak yerine geri dönmüyorsunuz !!? Bir fark var mı?
!!true #=> truevetrue.nil? #=> false
!boolean durumunu olumsuzlamak anlamına gelir, iki !s çift bir olumsuzlama dışında özel bir şey değildir.
!true == false
# => true
Genellikle bir yöntemi bir boole döndürmeye zorlamak için kullanılır. Dize, tamsayılar ve ne gibi her türlü gerçeği algılar ve boole dönüştürür.
!"wtf"
# => false
!!"wtf"
# => true
Daha gerçek bir kullanım durumu:
def title
"I return a string."
end
def title_exists?
!!title
end
Bu, bir boole döndürüldüğünden emin olmak istediğinizde kullanışlıdır. IMHO görerek olsa da, nazik anlamsız olduğunu hem if 'some string've if trueaynı akış, ancak bazı insanlar bunun yararlı açıkça bir boolean dönmek bulabilirsiniz.
title, ona en yakın şeyi de yapabilirsin ... Sanırım
Bu deyimin diğer programlama dillerinde de bulunduğunu unutmayın. C'nin kendine özgü bir booltürü yoktu , bu yüzden tüm booleanlar, intyerine 0veya değerlerinin kanonik değerleri ile yazıldı 1. Bu örneği alır (açıklık için parantez eklenmiştir):
!(1234) == 0
!(0) == 1
!(!(1234)) == 1
"Not-not" sözdizimi, sıfır olmayan herhangi bir tamsayıyı 1standart boolean true değerine dönüştürür.
Genel olarak, ancak, bu nadir deyimi kullanmaktan daha makul bir karşılaştırma yapmak daha iyi buluyorum:
int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious
Özel bir veya yapmanız gerekiyorsa yararlıdır . Matt Van Horn'un cevabından küçük değişikliklerle kopyalama:
1 ^ true
TypeError: can't convert true into Integer
!!1 ^ !!true
=> false
İki değişkenin ya sıfır ya da her ikisinin de nil olmadığından emin olmak için kullandım.
raise "Inconsistency" if !!a ^ !!b
Bu "çift negatiftir", ancak uygulama önerilmez. Rubocop kullanıyorsanız , bu tür kodlardan bir Style/DoubleNegationihlale karşı şikayet edildiğini göreceksiniz .
Mantık durumları:
Bu şifreli ve genellikle gereksiz hem olduğundan, kaçınılmalıdır [sonra başka sözcüklerle:] Değişim
!!somethingiçin!something.nil?
!!false # => falsesüre!false.nil? # => true
!(foo.nil? || foo == false)Kullanmazsanız, kullanabilirsiniz - daha ayrıntılı, evet, ama daha az şifreli.
Bir numaralandırmayı bir boole dönüştürmeniz gerekiyorsa, bunun nasıl çalıştığını anlamak yararlı olabilir. Ben classy_enumgem kullanarak tam olarak bunu yapan bir kod var :
class LinkStatus < ClassyEnum::Base
def !
return true
end
end
class LinkStatus::No < LinkStatus
end
class LinkStatus::Claimed < LinkStatus
def !
return false
end
end
class LinkStatus::Confirmed < LinkStatus
def !
return false
end
end
class LinkStatus::Denied < LinkStatus
end
Sonra hizmet kodu var, örneğin:
raise Application::Error unless !!object.link_status # => raises exception for "No" and "Denied" states.
Etkili bangbang operatör aksi takdirde to_bool denilen bir yöntem olarak yazmış olabilir ne oldu.