1

私がこれをしたら

x = y = z = 1
z = 20

それから私は得る

"#{x}----#{y}----#{z}"
# => "1----1----20" 

今、私がこのようなことをすると:

a = b = c = []

それから私はこれを得る:

"#{a}-----#{b}-----#{c}"
# => "[]-----[]-----[]"

しかし、私が次のことを行うと:

c[0] = 'a'
c[1] = 'b'
c[2] = 'c'

私はこれを得る:

"#{a}-----#{b}-----#{c}"
# => "[\"a\", \"b\", \"c\"]-----[\"a\", \"b\", \"c\"]-----[\"a\", \"b\", \"c\"]"

の場合x、、、、yz割り当てzたときに20、値xy保持しました1。についてArraysは、 だけに値を代入したのにc[]、 に変更が反映されましab。sに何が起こっているArrayのですか?

4

3 に答える 3

1

どのオブジェクトがどの変数に割り当てられているかを考えてください。結局のところ、変数は単にオブジェクトのハンドルです。ルビーでは、すべてがオブジェクトであり、変数はあなたがそれらと対話する方法です。

それで...

a = b = 1

これは、同じオブジェクトを設定aおよび参照します。b私が後で言うなら:

a = 2

次にa、まったく影響bを与えないはずの新しいオブジェクトを参照するように設定しました1。介入者は1つの簡単なステップを踏みます。

  1. ローカル変数aをオブジェクトに設定します2

しかし、その論理に従う:

a = b = []

繰り返しますが、同じオブジェクトaを参照します。b今回は配列。しかし今、これを行うと:

a[0] = 'hello'

ここには別のシナリオがあります。オブジェクトがa参照するものをまったく変更していません。オブジェクト参照を見つけて、そのオブジェクトaを変更しています。

通訳が何をするか考えてみてください。その行を実行するときは、次の手順を実行します。

  1. によって参照されるオブジェクトを検索しますa(これはたまたまによって参照されるオブジェクトと同じですb
  2. 0そのオブジェクトのインデックスの値を文字列に設定します"hello"

これはすべて、次のような単純なローカル変数の割り当てを言うことです。

a = 1

次のような間接層が存在する場合、操作は多少異なります。

a[0] = 'hello'
a.foo = 'bar'
a.set_value 'some val'

または、配列のメソッドを呼び出すように、配列に値を設定することを考えてください。したがって、次のように考えると、違いがわかりやすくなりますa[0] = 'foo'

a.set_value(0, 'foo')

このようなことは、実際にはルビー配列で起こることです。配列インデックスに値を割り当てると、[]=(index, value)メソッドが呼び出されます。これらはすべて有効で同等です。

a[0] = 'foo'
a.[]=(0, 'foo')
a.send('[]=', 0, 'foo')

これを指摘するのは、メソッドの呼び出しとして表現すると、ここで既存のオブジェクトを変更していることが非常に明確になるためです。

于 2012-10-07T08:40:23.497 に答える
1

を使用すると、別のオブジェクトを参照するようz = 20に変更されます。z

では、とも参照してc[0] = 'a'いる元のオブジェクトを変更しています。ab

于 2012-10-07T08:28:16.483 に答える
0

Ruby には、オブジェクトを変更するメソッドと、新しいオブジェクトを返すメソッドがあります (メソッドのドキュメントでこれについて言及されています)。整数は変更できません。2 は常に 2 になります。object_id をいじってみると、問題が解決する場合があります。

puts 1.object_id # 3
a = 1
puts a.object_id # 3
puts 20.object_id # 41
a = 20
puts a.object_id # 41

b = []
puts b.object_id # a number
b[1]=1 # mutating object
puts b.object_id # same number
b = b+[2] # the + method results in new object http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-2B
puts b.object_id # another number
于 2012-10-07T13:30:20.897 に答える