在`reduce`中使用带有累加器参数的`next`

时间:2016-09-17 20:27:48

标签: ruby coding-style rubocop

有警察:RuboCop::Cop::Lint::NextWithoutAccumulator

有人能够解释这个警察的用途,它应该以什么方式改进代码?

它是否提高了可读性和效率?

github code

2 个答案:

答案 0 :(得分:6)

让我们考虑一下文档中的示例代码:

# bad
result = (1..4).reduce(0) do |acc, i|
  next if i.odd?
  acc + i
end

如果您在控制台中尝试此操作,则NoMethodError对象将获得nil例外。这是因为如果没有指定对象,next“将返回”nil。对于迭代器,您可以将其视为return

对于reduce method,它可能会导致一些意外行为,因为它需要块返回的某些值。如果i为奇数,则会对next进行评估,然后阻止nil作为结果。在下面的迭代器acc等于nil,它不能向其添加整数。在我们的示例中,第一次迭代用于i = 1nextacc设置为nil作为块的结果。

在某些情况下,您可以获得可枚举的正确值,但一般来说,为next指定值更安全。

答案 1 :(得分:0)

if (context.ProtocolMessage.RedirectUri.Contains("http:"))
{                    
    context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http:", "https:");
}

result = (1..4).reduce(0) do |acc, i|
  next if i.odd?
  acc + i
end

正如@smefju指出的那样,next自身隐式返回result = (1..4).reduce(0) do |acc, i| next acc if i.odd? acc + i end ,并将其作为下一次执行块的参数传入时将导致nil