Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby中的多重引用_Ruby_Reference - Fatal编程技术网

Ruby中的多重引用

Ruby中的多重引用,ruby,reference,Ruby,Reference,我希望下面的代码打印“8”、“111”和“999”。我假设每个a、b、c和d都指向同一个内存位置。如果我通过其中一个改变位置,为什么另一个不改变?很明显,我的逻辑很差,或者我忽略了什么。而是打印“7”、“7”和“8” 为什么? [澄清] 我之所以感到困惑,是因为他们在那里改变了类似的值,但他们得到了我上面建议的结果。我们谈论的是同一个问题吗?它们没有指向相同的内存位置 它们不指向相同的内存位置 获得预期输出的最简单方法是使用单元素数组: a=b=c=d=[7] b[0] = 8 puts d[0

我希望下面的代码打印“8”、“111”和“999”。我假设每个a、b、c和d都指向同一个内存位置。如果我通过其中一个改变位置,为什么另一个不改变?很明显,我的逻辑很差,或者我忽略了什么。而是打印“7”、“7”和“8”

为什么?

[澄清]


我之所以感到困惑,是因为他们在那里改变了类似的值,但他们得到了我上面建议的结果。我们谈论的是同一个问题吗?

它们没有指向相同的内存位置

它们不指向相同的内存位置

获得预期输出的最简单方法是使用单元素数组:

a=b=c=d=[7]
b[0] = 8
puts d[0]
c[0] = 111
puts a[0]
d[0] = 999
puts b[0]

若要获取a和b是否引用同一对象,请使用
a.\uuuu id\uuu==b.\uu id\uuu
获取预期输出的最简单方法是使用单个元素数组:

a=b=c=d=[7]
b[0] = 8
puts d[0]
c[0] = 111
puts a[0]
d[0] = 999
puts b[0]
a=b=c=d=7
# a, b, c and d points to the same integer object "7"
     b  =  8
# b now points to a new object "8"
# "=" does not change the value of the pointer integer, 
# it assings a new reference like in the line above
     puts d
# obviously, d still points to "7"

     c  = 111
# c now points to another integer object "111"
     puts a
# a still points to "7"

     d  =  999
# d now points to a new integer object "999"
     puts b
# b still points to "8"
若要获取a和b是否引用同一个对象,请使用
a.\uuuu id\uuu==b.\uu id\uu

a=b=c=d=7
# a, b, c and d points to the same integer object "7"
     b  =  8
# b now points to a new object "8"
# "=" does not change the value of the pointer integer, 
# it assings a new reference like in the line above
     puts d
# obviously, d still points to "7"

     c  = 111
# c now points to another integer object "111"
     puts a
# a still points to "7"

     d  =  999
# d now points to a new integer object "999"
     puts b
# b still points to "8"
在Ruby中,Integer对象是不可变的,因此不能将整数分配给多个引用,也不能在引用后更改其值

正如@pts所建议的,您应该使用数组来包装整数引用,因为数组是可变的,您可以在之后更改值

a=b=c=d=[7]
b[0] = 8
puts d[0]
c[0] = 111
puts a[0]
d[0] = 999
puts b[0]
澄清:

如果你来自C++背景,这可能很奇怪,因为C++用相同的语法做2件事,分配引用和改变引用的值。

int a = 10; // creates an int on the stack with value 10
int& b = a; // creates a reference to an int and references the a variable
b = 5; // change the value referenced by b (so a) to 5
// a and b now hold the value 5
在Ruby中,引用是可变的,整数不是(与C++完全相反)。因此,指定引用实际上会更改引用,而不是引用值

另一种解决方案是创建一个可变整数类:

class MutableInteger
  attr_writer :value
  def initialize(value)
    @value = value
  end
  def inspect
    value
  end
  def to_i
    value
  end
  def to_s
    value
  end
end

a = b = MutableInteger.new(10)
a.value = 5
puts b
# prints 5
在Ruby中,Integer对象是不可变的,因此不能将整数分配给多个引用,也不能在引用后更改其值

正如@pts所建议的,您应该使用数组来包装整数引用,因为数组是可变的,您可以在之后更改值

a=b=c=d=[7]
b[0] = 8
puts d[0]
c[0] = 111
puts a[0]
d[0] = 999
puts b[0]
澄清:

如果你来自C++背景,这可能很奇怪,因为C++用相同的语法做2件事,分配引用和改变引用的值。

int a = 10; // creates an int on the stack with value 10
int& b = a; // creates a reference to an int and references the a variable
b = 5; // change the value referenced by b (so a) to 5
// a and b now hold the value 5
在Ruby中,引用是可变的,整数不是(与C++完全相反)。因此,指定引用实际上会更改引用,而不是引用值

另一种解决方案是创建一个可变整数类:

class MutableInteger
  attr_writer :value
  def initialize(value)
    @value = value
  end
  def inspect
    value
  end
  def to_i
    value
  end
  def to_s
    value
  end
end

a = b = MutableInteger.new(10)
a.value = 5
puts b
# prints 5

在第一行之后,a、b、c和d都指向同一个Fixnum对象(值为7)。但是,当执行b=8时,b现在指向一个新的Fixnum对象(值为8)

实际上,您将b指定给一个新对象,而不是改变现有对象。这就是为什么您的更改没有按预期传播的原因


如果与C++进行比较,这就像是用指针赋值指针,而不是用引用赋值。

第一行之后,A、B、C和D都指向同一个FixNUM对象(值7)。但是,当执行b=8时,b现在指向一个新的Fixnum对象(值为8)

实际上,您将b指定给一个新对象,而不是改变现有对象。这就是为什么您的更改没有按预期传播的原因


如果你与C++比较,这就像是用值赋值指针,而不是按引用赋值。

< P>我强烈推荐阅读

< P>我强烈推荐阅读

,好吧,这不是那么简单。如果将数组或散列传递给一个方法,则是通过引用传递,即不是复制它,因此如果该方法修改数组,则是修改原始数组。但是,是的,你不能摆弄指针,告诉变量指向同一个内存位置,等等——Ruby是不通过引用传递的。但由于每个变量实际上都是对对象的引用,因此在使用#dup之前不会复制对象。在OP的第一行之后,每个变量都指向同一个对象“7”。当然,这篇博文忽略了这一点,Java和Ruby通过引用传递。通过引用传递意味着不会将内存内容复制到方法参数中,而是复制引用。真正的区别在于affectation的工作方式:在C/C++中,您可以直接更改引用的内容,但在Ruby affectation中,只会更改变量包含的内容(即用另一个引用替换一个引用)。所以实际上我会说C/C++通过引用影响,Java/Ruby通过(变量的)值影响。Java是按值传递的,在使用本机类型而不是对象时,应该记住这一点。但既然Ruby拥有所有的对象,它就不再是一个问题了。如果将数组或散列传递给一个方法,则是通过引用传递,即不是复制它,因此如果该方法修改数组,则是修改原始数组。但是,是的,你不能摆弄指针,告诉变量指向同一个内存位置,等等——Ruby是不通过引用传递的。但由于每个变量实际上都是对对象的引用,因此在使用#dup之前不会复制对象。在OP的第一行之后,每个变量都指向同一个对象“7”。当然,这篇博文忽略了这一点,Java和Ruby通过引用传递。通过引用传递意味着不会将内存内容复制到方法参数中,而是复制引用。真正的区别在于affectation的工作方式:在C/C++中,您可以直接更改引用的内容,但在Ruby affectation中,只会更改变量包含的内容(即用另一个引用替换一个引用)。所以实际上我会说C/C++通过引用影响,Java/Ruby通过(变量的)值影响。Java是按值传递的,在使用本机类型而不是对象时,应该记住这一点。但由于Ruby拥有所有对象,所以它不是