2017-01-12 5 views
1

Stringオブジェクトの新しいインスタンスの値を作成するプロセスと、文字列リテラルの値を作成するプロセスとの違いを確認するのが難しいです。RubyのString.newと文字列リテラルの違いは何ですか?

a = String.new("Hello") 
# => "Hello" 

b = "Hello" 
# => "Hello" 

と私は

a == b 
# => true 

同じ値を実行する場合!どうしたの?

+3

'STR = "ああ、私は"' '' String.new( "ああ、私の")の省略形です、ほとんど。エンコーディングを含む違いについては、[String#new](http://ruby-doc.org/core-2.3.0/String.html#method-c-new)を参照してください。一般に、リテラル割り当てが使用されます。 –

答えて

1

==チェック:

あなたはこれらの変数は、実際に異なるオブジェクトであることを、確認するためにObject#object_idを使用することができます。

equal?は同一の同一性を検査する。

a = "hello" 
b = "hello" 

a == b # => true 
a.equal?(b) # => false 

Rubyの文字列リテラルでは不変ではないため、文字列の作成とリテラルの使用はまったく同じです。どちらの場合でも、Rubyは式が評価されるたびに新しい文字列インスタンスを作成します。

これらの両方は、のが、この

10.times { puts "".object_id } 

プリント10の異なる数

70227981403600 
70227981403520 
70227981403460 
... 

なぜを検証してみましょうので、同じ

10.times { String.new } 
# is the same as 
10.times { "" } 

ですか?文字列はデフォルトでは変更可能であるため、Rubyはソースコード内で文字列リテラルに達するたびにコピーを作成する必要があります。たとえそれらのリテラルが実際にはめったに変更されないとしても。

したがって、Rubyプログラムでは通常、余分な短命文字列オブジェクトが作成されるため、ガベージコレクションに大きな負担がかかります。 Railsアプリケーションが1つのリクエストを処理するためだけに50万個の短命文字列を作成することは珍しくありません。これは、数百万人、さらには100万人のユーザーにRailsを拡張する際の主要なパフォーマンスボトルネックの1つです。

Ruby 2.3では、フリーズした文字列リテラルが導入されました。ここでは、すべての文字列リテラルがデフォルトで不変になっています。これは、オプトインされるプラグマ

# frozen_string_literal: true 

でのこのあまりに

# frozen_string_literal: true 
10.times { puts "".object_id } 

同じ数を10回

69898321746880 
69898321746880 
69898321746880 
... 

楽しい事実をプリントを検証してみましょう、後方互換性がありませんので、ハッシュでキーを設定すると、文字列のコピーも作成されます

str = "key" 
hash = {} 
hash[str] = true 
puts str.object_id 
puts hash.keys.first.object_id 

プリント二つの異なる数字

70243164028580 
70243132639660 
4

文字列リテラルは文字列オブジェクトです。以前のバージョンのRubyでは違いはありません。

Ruby 2.3では、文字列リテラルをフリーズすることができます。文字列は変更できませんので、

x = "Hello" 
x.upcase! 

...エラーが発生します...これは意味のRuby 3.0

で計画デフォルトです。コンストラクタを使用して

...

x = String.new("Hello") 
x.upcase! 

作品罰金。

1

あなたの例では、abは、ポインタではなくcのような参照です。したがって、オブジェクトではなく値を比較しています。

1

同じ値!どうしたの?

何も起こりませんが、同じ値を持つ無限の数のローカル変数を作成できます。同じコンテンツの

a = String.new("Hello") 
b = "Hello" 
a.object_id #=> 70295696460580 
b.object_id #=> 70295696294220 
関連する問題