我无法理解为什么在Ruby中,Array#slice
和Array#slice!
的行为与Array#sort
和Array#sort!
的行为不同(就像在新数组中返回结果一样)而另一个在当前对象上工作。)
使用sort
第一个(没有爆炸),返回当前数组的已排序副本,sort!
对当前数组进行排序。
slice
,返回具有指定范围的数组,slice!
删除当前对象的指定范围。
Array#slice!
的行为是什么原因,而不是让当前对象成为具有指定范围的数组?
示例:
a = [0,1,2,3,4,5,6,7,8,9]
b = a.slice( 2,2 )
puts "slice:"
puts " a = " + a.inspect
puts " b = " + b.inspect
b = a.slice!(2,2)
puts "slice!:"
puts " a = " + a.inspect
puts " b = " + b.inspect
输出:
slice:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [2, 3]
slice!:
a = [0, 1, 4, 5, 6, 7, 8, 9]
b = [2, 3]
答案 0 :(得分:3)
#slice
和#slice!
行为是等效的:“返回从开始索引开始的子数组并继续 length 元素”,与#sort
和#sort!
相同的方式返回已排序的数组或#reverse
和#reverse!
返回反向数组。
不同之处在于爆炸方法也会修改对象本身。
a = [4,2,6,9,1,5,8]
b = a.dup
a.sort == b.sort! # => true
a == b # => false
b = a.dup
a.reverse == b.reverse! # => true
a == b # => false
b = a.dup
a.slice(2,2) == b.slice!(2,2) # => true
a == b # => false
答案 1 :(得分:1)
!
或bang方法通常会改变现有对象而不是返回新对象的非等价方法等效方法。如果要修改现有对象,请使用bang方法选项。
编辑:
为了解决设计决策,我不是Matz,但我猜这是因为slice
的本质是返回一个子集,它会在每种情况下返回子集。对于其他爆炸方法,例如gsub
或sort
,您正在修改(可能)整个字符串/对象,以便它返回副本或返回原始变量。
答案 2 :(得分:0)
我认为设计决策背后的想法是,如果你调用Array#slice!
,那么你已经有一个指向数组切片的指针(假设你将它分配给一个变量)。逻辑决定是修改对象,使切片不再在原始数组中。
例如,您可以看到这在循环中如何有用。如果你想继续分析数组的前3个元素,用这3个元素做一些事情,并在没有更多元素时停止,你可以使用Array#slice!
并最终破坏数组。
现在,如果您想象示例中的数组是队列或堆栈,那么为什么要删除数组的部分是有意义的。