Ruby 为什么阵列#切片和阵列#切片!表现不同?
我不明白为什么在Ruby中,Ruby 为什么阵列#切片和阵列#切片!表现不同?,ruby,behavior,design-decisions,Ruby,Behavior,Design Decisions,我不明白为什么在Ruby中,Array#slice和Array#slice的行为不同于Array#sort和Array#sort(一个返回新数组的结果,另一个处理当前对象) 使用sort第一个数组(不带bang),返回当前数组的已排序副本,然后sort对当前数组进行排序 slice,返回具有指定范围的数组,然后slice从当前对象删除指定范围 数组#切片的原因是什么的行为与此类似,而不是使当前对象成为具有指定范围的数组 例如: a=[0,1,2,3,4,5,6,7,8,9] b=a.切片(2,2
Array#slice
和Array#slice代码>的行为不同于Array#sort
和Array#sort代码>(一个返回新数组的结果,另一个处理当前对象)
使用sort
第一个数组(不带bang),返回当前数组的已排序副本,然后sort代码>对当前数组进行排序
slice
,返回具有指定范围的数组,然后slice代码>从当前对象删除指定范围
数组#切片的原因是什么代码>的行为与此类似,而不是使当前对象成为具有指定范围的数组
例如:
a=[0,1,2,3,4,5,6,7,8,9]
b=a.切片(2,2)
放入“切片”:
将“a=”+a
放入“b=”+b
b=a.切片!(2,2)
放入“切片!”
将“a=”+a
放入“b=”+b
输出:
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]
或bang方法通常会改变现有对象,而不是返回新对象的非bang方法等价物。如果要修改现有对象,请使用“bang方法”选项
编辑:
为了解决设计决策问题,我不是Matz,但我想,因为slice
的本质是返回一个子集,所以它在每种情况下都返回子集。对于其他bang方法,如gsub
或sort
,您正在(可能)修改整个字符串/对象,以便它返回一个副本或返回带有更改的原始字符串/对象。#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
我认为设计决策背后的想法是,如果调用Array#slice
那么您已经有了一个指向数组切片的指针(假设您将其分配给了一个变量)。合乎逻辑的决定是修改对象,使切片不再位于原始数组中
例如,您可以看到这在循环中是多么有用。如果您想继续获取数组前3个元素的切片,请对这3个元素执行某些操作,并在没有更多元素时停止,您可以使用array#slice
最终会破坏阵列
现在,如果您假设示例中的数组是一个队列或堆栈,那么您可以理解为什么要删除部分数组。这不是用户所要求的。他知道这一点,他在询问设计决策。具体来说,为什么要切片!不会用结果替换当前对象。@SimoneCarletti这可能有帮助吗?使用方法上的code>没有设置行为,它只是指示该方法以某种方式改变输入,同时也具有完全相同的输出。您可以将它添加到您编写的任何方法的末尾。这不是用户要求的。他知道这一点,他在询问设计决策。具体来说,为什么要切片!不使用结果替换当前对象。#slice
(和#slice!
)“如果索引超出范围,则返回nil”。这种情况与用返回值替换对象的想法不一致,这可能是我迄今为止读过的最好的解释之一+1我不得不这么说=/我对bang方法的想法是错误的。