2016-05-02 5 views
-1

Ich sah, dass object_id von Strings immer anders ist, während Symbole object_id das gleiche ist (wenn der Wert gleich ist). Wie ich verstehe, ist der Unterschied zwischen Symbolen und Strings Unveränderlichkeit und Leistung. Können wir nicht einfach einen String in einer Variablen speichern und einfrieren?Symbole (Speichern von Strings in Variablen vs Symbole)

Antwort

1

[...] können wir nicht einfach einen String in einer Variablen speichern und einfrieren?

Fast, aktuelle Versionen von Ruby können gefrorene Strings optimieren:

'foo'.freeze.object_id #=> 70313275108080 
'foo'.freeze.object_id #=> 70313275108080 

Aber diese Optimierung ist begrenzt. Es funktioniert für String Literale (wie oben dargestellt), aber es funktioniert nicht, wenn die Zeichenfolge später gefroren ist:

a = 'foo' 
a.freeze 
a.object_id #=> 70313275335500 

b = 'foo' 
b.freeze 
b.object_id #=> 70313275274260 

Sofern Sie die frozen_string_literal Funktion aktivieren:

# frozen_string_literal: true 

puts 'foo'.object_id 
puts 'foo'.object_id 

Ausgang:

$ ruby test.rb 
70185151269500 
70185151269500 

Oder von der Kommandozeile:

$ ruby --enable-frozen-string-literal -e "puts 'foo'.object_id, 'foo'.object_id" 
70102955495340 
70102955495340 
+0

Also wo Strings zu verwenden und wo Symbole dann zu verwenden? –

+0

@ RamziddinMakhmudov Verwenden Sie eine Zeichenfolge, wenn ihr Inhalt wichtig ist, d. H. Die Zeichen. Wenn Sie einen Bezeichner oder ein Label benötigen, verwenden Sie ein Symbol. – Stefan

+0

Danke für die saubere und verständliche Antwort =) –

0

freeze verhindert die Änderung des tatsächlichen Objekts, jedoch sind Variablen Verweise auf Objekte, so dass Sie die Referenz noch ändern können. Das Folgende ist zum Beispiel vollkommen gültig.

a = "foo" 
a.freeze 
a = "boo" 

Am Ende dieser a ist gleich "boo".

In Ruby-Versionen 2.1 und älter ein Symbol ist eine verfügbare object_id zugeordnet und zu jeder Zeit die gleiche Symbol-ID verwendet wird die gleiche object_id wird immer verwendet werden; Dies ist nie Müll gesammelt. Dies ist unveränderbar, aber es ist auch effizienter (weniger Speicheraufwand).

In Ruby-Versionen 2.2 und höher ist das Verhalten im Grunde das gleiche, außer Symbole können Müll gesammelt werden. Der Grund für diese Änderung war, einen Symbol-DoS-Angriff zu verhindern.

+0

Wo also Strings und wo Symbole dann verwenden? –

+0

Vielen Dank für Ihre Antwort! Ich werde über Symbol DoS-Angriff lesen :) –