奇怪的特征? 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
指向赋值后的新对象。
但是,当您分配给单个数组元素时,您不会创建一个全新的数组,因此a
和b
继续指向您刚刚更改的同一个对象。
如果您正在寻找数组的变异与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,因为两个变量都引用相同的字符串对象。
至于深度复制,这里有一个不错的部分: