为什么我不能在这里使用splat运算符而不是self?

时间:2013-04-06 13:25:03

标签: ruby

这是有效的:

def sum
  result = 0
  self.each { |num| result += num }
  result
end

为什么这不起作用?

def sum(*numbers)
  result = 0
  numbers.each { |num| result += num }
  result
end

测试:传入[4,6,9],应该得到总和。顶部函数有效,底部函数不添加它们。

乱七八糟地发现,self.并不是保持测试通过所必需的。这只是好形式吗?

4 个答案:

答案 0 :(得分:0)

  def sum(*numbers)
    result = 0
    numbers.each { |num| result += num }
    result
  end
  p sum(1,2,3)

class Array
def sum
    result = 0
    self.each { |num| result += num }
    result
end
end
p ([1,2,3].sum)

输出:

6

请勿执行以下操作:

  def sum(*numbers)
    p numbers
    result = 0
    numbers.each { |num| result += num }
    result
  end
  p sum([1,2,3])

输出:

[[1, 2, 3]]
true.rb:255:in `+': Array can't be coerced into Fixnum (TypeError)
    from true.rb:255:in `block in sum'
    from true.rb:255:in `each'
    from true.rb:255:in `sum'
    from true.rb:258:in `<main>'

答案 1 :(得分:0)

numbers参数将所有传递给该方法的参数作为数组。

但是你传递了一个参数 - 数组,所以你有一个嵌套数组。

要解决此问题,您可以使用flatten方法将嵌套数组转换为平面数组。

def sum(*numbers)
  result = 0
  numbers.flatten.each { |num| result += num }
  result
end

答案 2 :(得分:0)

问题

当您使用splat收集参数时,您将它们收集到一个数组中。如果将数组传递给splat,则会得到一个嵌套数组。例如:

def sum(*numbers)
  numbers.inspect
end
#=> [[4, 6, 9]]

在这种情况下,Array#each将返回[4, 6, 9]作为其唯一成员。

解决方案

如果您知道要传入数组,则可以使用Enumerable#reduce代替。例如:

def sum array
  array.reduce :+
end

sum [4, 6, 9]
#=> 19

答案 3 :(得分:0)

或者你可以试试这个:

def sum(*numbers)
  numbers.flatten.reduce(:+)
end

这样您就可以sum(1,2,3)sum([1,2,3])调用它。