为什么Array#slice和Array#slice!表现不同?

Var*_*gas 8 ruby behavior design-decisions

我无法理解为什么,在Ruby中, Array#slice并且Array#slice!行为Array#sortArray#sort!(和一种方式在新数组上返回结果而另一种在当前对象上工作的方式)不同.

使用sort第一个(没有爆炸),返回当前数组的排序副本,并对当前数组进行sort!排序.

slice,返回具有指定范围的Array,并从当前对象中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
Run Code Online (Sandbox Code Playgroud)

输出:

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]
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/77xFva

wac*_*cko 5

#slice和行为是等效的:都“返回从起始#slice!索引开始并继续长度元素的子数组”,与返回排序数组或返回反转数组的方式相同。#sort#sort!#reverse#reverse!

不同之处在于 bang 方法还会修改对象本身。

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
Run Code Online (Sandbox Code Playgroud)

  • `#slice` (和​​ `#slice!`)_“如果索引超出范围则返回 nil”_。这种情况与用返回值替换对象的想法不兼容 (3认同)