奇怪的特征? Ruby数组

我在Ruby中遇到了这个奇怪的数组(?),如果有人可以向我解释他们为什么按照他们的方式工作,那将会非常有用。

首先让我们举例说明事情通常是如何运作的。

a = "Hello" #=> "Hello" b = a #=> "Hello" b += " Goodbye" #=> "Hello Goodbye" b #=> "Hello Goodbye" a #=> "Hello" 

好吧,当你使用=时,它会创建一个对象的副本(这次是一个字符串)。

但是当你使用数组时会发生这种情况

 a = [1,2,3] #=> [1,2,3] b = a #=> [1,2,3] b[1] = 5 #=> [1,5,3] b #=> [1,5,3] a #=> [1,5,3] 

现在那只是奇怪的。 它是我发现的唯一一个在使用=时不会被复制的对象,而只是创建一个对原始对象的refrance。

有人也可以解释(必须有一个方法)复制数组而不指向原始对象吗?

实际上,你应该重新审视你的前提。

字符串赋值实际上是b = b + " Goodbye"b + " Goodbye"操作返回一个全新的字符串,因此变量 b指向赋值后的新对象。

但是,当您分配给单个数组元素时,您不会创建一个全新的数组,因此ab继续指向您刚刚更改的同一个对象。

如果您正在寻找数组的变异与function行为的基本原理,那很简单。 修改字符串没有任何好处。 最有可能的是必须分配新的内存,因此创建了一个全新的字符串。

但arrays可以任意大。 创建一个新数组只是为了改变一个元素可能非常昂贵。 无论如何,数组就像任何其他复合对象一样。 更改单个属性不一定会影响任何其他属性。

要回答你的问题,你可以随时做:

 b = a.dup 

发生的事情是ruby通过引用而不是值来处理Array对象。

所以你可以这样看:

  b= [1,2,3] a= b --'b' Points to---> [1,2,3] <--'a' points t--- 

因此,你可以看到两者都指向相同的引用,这意味着如果你改变它的任何东西将反映在b上。

至于关于复制对象的问题,您可以使用Object#clone方法来执行此操作。

尝试使用字符串的数组案例:

 a = "Hello" #=> "Hello" b = a #=> "Hello" b[1] = "x" #=> "x" b #=> "Hxllo" a #=> "Hxllo" 

在这方面,字符串和数组的工作方式相同。

正如你所写的那样,这两种情况的关键区别在于:

 b += " Goodbye" 

这是语法的简写

 b = b + " Goodbye" 

这是从b + " Goodbye"创建一个新字符串,然后将其分配给b。 修改现有字符串而不是创建新字符串的方法是

 b << " Goodbye" 

如果你将它插入你的序列,你会发现它修改了a和b,因为两个变量都引用相同的字符串对象。

至于深度复制,这里有一个不错的部分:

http://ruby.about.com/od/advancedruby/a/deepcopy.htm