7

我一直在玩数组,发现自己无法理解以下代码:

first_array = []
second_array = []
third_array = []                         # I initialized 3 empty arrays

third_array << [1,2,3,4,5,6,7,8,9]       # I loaded 1..9 into third_array[0]
puts third_array.size                    # => 1

first_array << third_array               # 1..9 was loaded into first_array[0]

second_array += third_array              # 1..9 was loaded into second_array[0]

puts first_array == third_array          # false
puts second_array == third_array         # true
puts first_array == second_array         # false

puts first_array.size                    # 1
puts second_array.size                   # 1
puts third_array.size                    # 1

这是怎么回事?

second_array += third_array              # I have no clue

为什么不是所有的数组都彼此相等?

4

3 回答 3

8

他们表现出相当不同的行为。一个创建并分配一个新Array对象,另一个修改现有对象。

+=将与 相同second_array = second_array + third_array。这会将+消息发送到作为参数second_array传递的对象。third_array

根据文档Array.+返回一个通过连接两个数组构建的新数组对象。这将返回一个新对象。

Array.<<只需将参数推送到现有数组对象的末尾:

second_array = []
second_array.object_id = 1234

second_array += [1,2,3,4]
second_array.object_id = 5678

second_array << 5
second_array.object_id = 5678

添加参数的方式也有所不同。通过添加其他元素,这将有助于了解为什么您的数组不相等:

second_array = [1, 2, 3]

# This will push the entire object, in this case an array
second_array << [1,2]
# => [1, 2, 3, [1,2]]

# Specifically appends the individual elements,
# not the entire array object
second_array + [4, 5]
# => [1, 2, 3, [1,2], 4, 5]

这是因为Array.+使用连接而不是推送。与Array.concat修改现有对象不同,Array.+返回一个新对象。

你可以想象一个 Ruby 实现,比如:

class Array
  def +(other_arr)
    dup.concat(other_arr)
  end
end

在您的具体示例中,您的对象最后看起来像这样:

first_array  = [[[1, 2, 3, 4, 5, 6, 7, 8, 9]]] # [] << [] << (1..9).to_a
second_array =  [[1, 2, 3, 4, 5, 6, 7, 8, 9]]  # [] + ([] << (1..9).to_a)
third_array  =  [[1, 2, 3, 4, 5, 6, 7, 8, 9]]  # [] << (1..9).to_a
于 2013-05-07T21:00:27.843 回答
3

<<将项目附加到数组

+=将数组添加到数组中。

例子:

[1,2] << 3# 返回 [1,2,3]

[1,2] += [3,4]# 返回 [1,2,3,4]

于 2013-05-07T21:00:34.360 回答
3

<<和之间迄今为止没有提到的最后一个区别+=是,它<<是一种方法:

class Array
  def << other
    # performs self.push( other )
  end
end

而是+=语法:

a += b

并且只是写作的简写:

a = a + b

因此,为了修改+=行为,必须修改+方法:

class Array
  def + other
    # ....
  end
end
于 2013-05-07T21:35:00.867 回答