139 Stimmen

Was bedeutet !! in Ruby?

Fragte mich nur, was !! in Ruby ist.

167voto

Alex Wayne Punkte 160481

Nicht nicht.

Es wird verwendet, um einen Wert in einen booleschen Wert umzuwandeln:

!!nil   #=> false
!!"abc" #=> true
!!false #=> false

Es ist normalerweise nicht notwendig, es zu verwenden, da die einzigen falschen Werte für Ruby nil und false sind, daher ist es in der Regel am besten, diese Konvention zu lassen.

Denk daran als

!(!some_val)

Etwas, wofür es legitim verwendet wird, ist das Verhindern, dass ein großer Datenblock zurückgegeben wird. Zum Beispiel möchtest du wahrscheinlich keine 3 MB an Bilddaten in deiner has_image?-Methode zurückgeben oder du möchtest vielleicht nicht dein gesamtes Benutzerobjekt in der logged_in?-Methode zurückgeben. Durch Verwendung von !! werden diese Objekte in ein einfaches true/false umgewandelt.

8 Stimmen

Es ist keine schlechte Praxis, dies zu verwenden. Doppel-Bang wird häufig in Prädikaten (Methoden, die mit ? enden) verwendet, um einen explizit booleschen Wert zurückzugeben.

6 Stimmen

Alex, du musst dir eigentlich keine Sorgen machen, große Objekte zurückzugeben, da Ruby eine Referenz zurückgibt, nicht eine Kopie des Objekts.

10 Stimmen

@DSimon, manchmal muss man sich doch Gedanken über große Objekte machen, zum Beispiel beim Drucken oder Protokollieren eines Werts während des Debuggens.

31voto

RichH Punkte 6090

Es gibt true zurück, wenn das Objekt rechts nicht nil und nicht false ist, false, wenn es nil oder false ist

def eingeloggt?   
  !!@current_user
end

1 Stimmen

War es offensichtlich, dass es von Restful_Auth kam?! :D

14voto

August Lilleaas Punkte 52649

! bedeutet den negierten booleschen Zustand, zwei ! ist nichts Besonderes, außer einer doppelten Verneinung.

!true == false
# => true

Es wird häufig verwendet, um eine Methode zur Rückgabe eines booleschen Wertes zu zwingen. Es erkennt jede Art von Wahrheitsgehalt, wie z.B. Strings, Integer und dergleichen, und wandelt sie in einen booleschen Wert um.

!"wtf"
# => false

!!"wtf"
# => true

Ein realeres Anwendungsbeispiel:

def titel
  "Ich gebe einen String zurück."
end

def titel_existiert?
  !!titel
end

Dies ist nützlich, wenn Sie sicherstellen möchten, dass ein boolescher Wert zurückgegeben wird. Meiner Meinung nach ist es jedoch irgendwie sinnlos, da sowohl if 'some string' als auch if true denselben Verlauf haben, aber einige Leute es nützlich finden, explizit einen booleschen Wert zurückzugeben.

0 Stimmen

Es scheint mir einfach eine schnellere Methode zu sein, als ein if-Statement oder ein ternärer Operator zu verwenden. Da man nicht einfach title zurückgeben kann, ist es wohl das Nächstbeste... würde ich sagen.

6voto

Tom Punkte 10491

Beachten Sie, dass dieses Idiom auch in anderen Programmiersprachen existiert. C hatte keinen intrinsischen bool-Typ, also wurden alle Booleans stattdessen als int getypt, mit den kanonischen Werten von 0 oder 1>. Betrachte dieses Beispiel (Klammern für Klarheit hinzugefügt):

``!(1234) == 0 !(0) == 1 !(!(1234)) == 1

Die "nicht-nicht" Syntax wandelt jede Nicht-Null-Integer in 1, den kanonischen Wahrheitswert, um.

Im Allgemeinen finde ich es jedoch viel besser, einen vernünftigen Vergleich einzufügen, anstatt dieses ungewöhnliche Idiom zu verwenden:

int x = 1234;
if (!!x); // wtf mate
if (x != 0); // offensichtlich``

0 Stimmen

Oder einfach if (x). !! ist nützlich, wenn Sie entweder 0/1 benötigen. Sie können auch (x) ? 1 : 0 klarer betrachten.

3voto

Andrew Grimm Punkte 73882

Es ist nützlich, wenn Sie ein ausschließendes Oder benötigen. Kopiert von Matt Van Horn's Antwort mit leichten Änderungen:

1 ^ true
TypeError: true kann nicht in Integer umgewandelt werden

!!1 ^ !!true
=> false

Ich habe es verwendet, um sicherzustellen, dass zwei Variablen entweder beide nil sind oder beide nicht nil sind.

wenn !!a ^ !!b
raise "Inkonsistenz"

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X