it-swarm.com.de

Was ist der Doppelpunktoperator in Ruby?

Wenn ich sage { :bla => 1, :bloop => 2 }, was genau macht das : machen? Ich habe irgendwo darüber gelesen, wie es einer Zeichenkette ähnelt, aber irgendwie ein Symbol.

Ich bin mir nicht ganz sicher, ob mich jemand aufklären kann?

222
LuxuryMode

:foo ist ein Symbol mit dem Namen "foo". Symbole zeichnen sich dadurch aus, dass zwei gleichnamige Symbole identisch sind:

"foo".equal? "foo"  # false
:foo.equal? :foo    # true

Dies macht das Vergleichen von zwei Symbolen sehr schnell (da nur ein Zeigervergleich erforderlich ist, anstatt alle Zeichen wie in einer Zeichenfolge zu vergleichen), und Sie werden nicht zig Kopien desselben Symbols im Umlauf haben.

Außerdem sind Symbole im Gegensatz zu Zeichenfolgen unveränderlich.

241

Nur um einige der in den Antworten genannten Dinge zu demonstrieren:

require 'benchmark'

n = 1_000_000

print '"foo".equal? "foo" -> ', ("foo".equal? "foo"), "\n"
print '"foo" == "foo"     -> ', ("foo" == "foo"    ), "\n"
print ':foo.equal? :foo   -> ', (:foo.equal? :foo  ), "\n"
print ':foo == :foo       -> ', (:foo == :foo      ), "\n"

Benchmark.bm(10) do |b|
  b.report('string')     { n.times { "foo".equal? "foo" }}
  b.report('str == str') { n.times { "foo" == "foo"     }}
  b.report('symbol')     { n.times { :foo.equal? :foo   }}
  b.report('sym == sym') { n.times { :foo == :foo       }}
end

Ausführen von it-Ausgaben:

"foo".equal? "foo" -> false
"foo" == "foo"     -> true
:foo.equal? :foo   -> true
:foo == :foo       -> true

Vergleichen einer Zeichenfolge mit einer Zeichenfolge mithilfe von equal? schlägt fehl, weil sie unterschiedliche Objekte sind, auch wenn sie den gleichen Inhalt haben. == vergleicht den Inhalt und die entsprechenden Prüfungen mit Symbolen sind viel schneller.

                 user     system      total        real
string       0.370000   0.000000   0.370000 (  0.371700)
str == str   0.330000   0.000000   0.330000 (  0.326368)
symbol       0.170000   0.000000   0.170000 (  0.174641)
sym == sym   0.180000   0.000000   0.180000 (  0.179374)

Beide Symboltests sind in Bezug auf die Geschwindigkeit grundsätzlich gleich. Nach 1.000.000 Iterationen gibt es nur 0,004733 Sekunden Unterschied, also würde ich sagen, dass es ein Waschschritt ist, zwischen dem man verwendet.

44
the Tin Man

Symbole sind eine Möglichkeit, Zeichenfolgen und Namen in Ruby darzustellen.

Der Hauptunterschied zwischen Symbolen und Zeichenfolgen besteht darin, dass Symbole mit demselben Namen initialisiert werden und während einer Ruby-Sitzung nur einmal im Speicher vorhanden sind.

Sie sind nützlich, wenn Sie dasselbe Wort verwenden müssen, um verschiedene Dinge darzustellen

31
nunopolonia

Es gibt einige Zitate aus dem berühmten Buch Agile Web Development with Rails , die hilfreich sein können, um auch das Symbol zu verstehen :

Rails verwendet Symbole, um Dinge zu identifizieren. Insbesondere werden sie als Schlüssel verwendet, wenn Methodenparameter benannt und in Hashes nachgeschlagen werden.

redirect_to :action => "edit", :id => params[:id]

Sie können sich Symbole als String-Literale vorstellen, die auf magische Weise zu Konstanten gemacht werden. Alternativ können Sie den Doppelpunkt als "das Ding mit dem Namen" ansehen. Id ist also "das Ding mit dem Namen id".

17
shyan1

In Ruby Jedes Objekt hat eine eindeutige Objektkennung. Wenn Sie puts "hello".object_id In Ihren IRB schreiben und zweimal die Eingabetaste drücken, erhalten Sie zwei unterschiedliche Rückgabewerte schreibe 2 mal :hello.object_id, es wird nur der gleiche Rückgabewert ausgegeben, was den Unterschied hätte erklären sollen.

4
Devin Huang

Wenn du benutzt :foo => bar, foo wird ein Symbol sein. Der Vorteil von Symbolen ist, dass sie einzigartig sind. Wenn Sie einen Gegenstand im Hash aufrufen, tun Sie hash[:foo].

Symbole benötigen weniger Speicher als Zeichenfolgen, was sie auch nützlich macht, wenn Sie Ihr Programm etwas schneller machen möchten.

2
Charles

Alle diese Antworten lassen ein besonders verlockendes Detail aus. Wenn Sie das Symbol "foo" eingeben, erhalten Sie. Raten Sie, was. Die Zeichenfolge "foo". Daher

irb(main):025:0>
irb(main):026:0> :foo
=> :foo
irb(main):027:0> "#{:foo}"
=> "foo"
irb(main):028:0>
irb(main):029:0> 'foo' <=> :foo
=> nil
irb(main):030:0> 'foo' <=> :foo.to_s
=> 0
irb(main):031:0>

Daher ... für Perl-Programmierer ... ist es Rubys Antwort auf das "nackte Wort".

0
Frank Carnovale

Es ist ein Symbol. Grundsätzlich sagen Sie, dass die beiden Elemente des Hashs die Schlüssel bla und bloop haben, so als hätten Sie die Zeichenfolgen "bla" und "bloop". Sie belegen jedoch weniger Speicher als Zeichenfolgen und sind einfacher zu tippen.

0
kindall