我有一个填充了默认字符串的数组,我试图在随机位置替换默认字符串中的部分字符。
如果我做这样的事情,我将改变数组中的所有元素:
arr = ["*"] * 10
arr[0][0..2] = "aaa"
arr
# => ["aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa"]
但是如果我以不同的方式初始化数组,它可以工作:
(0..10).each.map {|i| arr[i] = "*"}
arr[0][0..2] = "aaa"
arr
# => ["aaa", "*", "*", "*", "*", "*", "*", "*", "*", "*", "*"]
更多,初始化和所有元素相同:
str = "*"
(0..10).each.map {|i| arr[i] = str}
arr[0][0..2] = "aaa"
arr
# => ["aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa"]
相反,我这样做是为了用独特的元素初始化它:
str = "*"
(0..10).each.map {|i| arr[i] = "#{str}" }
arr[0][0..2] = "aaa"
arr
# => ["aaa", "*", "*", "*", "*", "*", "*", "*", "*", "*"]
这种行为的背景是什么?
答案 0 :(得分:4)
Arrays存储对象的引用。以这种方式初始化数组时,会得到一个包含对同一字符串的十个引用的数组。然后修改字符串。
arr = ['*']*3
# => ["*", "*", "*"]
arr.map &:object_id
# => [70305424624600, 70305424624600, 70305424624600]
相比之下,ruby为每个元素分配一个新字符串:
Array.new(3){ '*' }.map &:object_id
# => [70184497001120, 70184497001060, 70184497001000]
答案 1 :(得分:1)
执行arr=["*"]*10
时,您将完全相同的String
对象放入所有阵列插槽中。然而,(0..10).each.map { |i| arr[i] = "*" }
正在为数组中的每个元素创建一个新的String
对象。
使用以下代码进行说明:
(0..10).each.map { |i| arr[i] = "*" }
arr[0].equal? arr[1] # Check if first and second elements point to same Object
# => false
arr = ["*"] * 10
arr[0].equal? arr[1]
# => true
答案 2 :(得分:0)
arr = ["*"]*10
此语句创建一个包含10个元素的数组,但所有这些元素都不是唯一的,并且指的是在填充数组之前创建的字符串" *" 的相同实例。我的意思是你的代码与:
相同a = "*"
arr = [a, a, a, a, a, a, a, a, a, a]
#=> ["*", "*", "*", "*", "*", "*", "*", "*", "*", "*"]
arr.map(&:object_id)
#=> [15424420, 15424420, 15424420, 15424420, 15424420, 15424420, 15424420, 15424420, 15424420, 15424420]
数组的所有元素都引用相同的字符串实例,因此当您更改数组中的任何元素值时,您实际上会更改 a 变量的值,因此您将获得相同的数组填充了 a 变量,但由于其值已更改为" aaa" ,因此输出将如下所示:
["aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa"]
在第二个示例中,您使用" *" 字符串的新实例填充数组的每个元素,因此当您更改单个数组值时,它将仅影响此具体元素数组和其他所有数组都是相同的,因为它们引用内存中不同的已分配对象。
arr = (0..10).each.map { |i| arr[i] = "*" }
#=> ["*", "*", "*", "*", "*", "*", "*", "*", "*", "*"]
arr.map(&:object_id)
#=> [14451520, 14451500, 14451480, 14451440, 14451420, 14451320, 14451300, 14451280, 14451260, 14451240, 14451160]