如果没有进行任何更改,Array
方法的某些爆炸版本就像compact!
,reject!
,flatten!
,uniq!
返回nil
:
[1,[2]].flatten!
# => [1, 2]
[1,2].flatten!
# => nil
[1,[2]].flatten
# => [1, 2]
[1,2].flatten
# => [1, 2]
[1,2,nil].compact!
# => [1, 2]
[1,2].compact!
# => nil
[1,2,nil].compact
# => [1, 2]
[1,2].compact
# => [1, 2]
如果他们这样做,就必须有理由。任何想法可能是什么?
答案 0 :(得分:18)
bang(!
)方法会修改当前对象,但如果每个the documentation没有受影响的元素,它们会返回nil
。如果您因为某种原因需要执行某些操作(如果您修改了相关数组),这将非常有用。
if array.flatten!
puts "Oh yeah... flattened that array!"
end
答案 1 :(得分:4)
我总是留下印象 bang版本的
Array
方法是 只是他们的方式不同 修改对象。
这里的问题可能是这种印象不是真正的印象:according to David A. Black, !
并不意味着该方法会更改其接收方; !
表示此方法是其他等效方法的“危险”版本,其名称与!
相同。
现在危险有多种形式(强调我的):
有时你会得到不止一种 甚至在一声巨响中“危险” 方法。拿
String#gsub!
。这个 方法更改其接收器:str = "David" str.gsub!(/$/, " Black") str # David Black
它也不同于
gsub
(非爆炸) 如果字符串没有改变,gsub
返回未更改的副本 字符串但gsub!
返回nil:str.gsub(/xyz/, "blah") # David Black str.gsub!(/xyz/, "blah") # nil str # David Black
!在
gsub!
中为您提供了一个单挑: 它警告你危险,这意味着 在你使用这个方法之前,你 应该弄清楚它是怎么回事 行为。(简单的“ri String#gsub!
” 应该这样做。)
这种“单挑”语义也适用于Array
的爆炸方法。