没有将 Enumerator 隐式转换为 Array
No implicit conversion of Enumerator into Array
我有:
qs = ["all=true", "limit=-1"]
value = ["agent", "service", "token"]
此代码:
qs.concat value.map do |val|
"#{field}=#{val}"
end
最终出现以下错误:
`concat': no implicit conversion of Enumerator into Array (TypeError)`
而这段代码:
values = value.map do |val|
"field=#{val}"
end
qs.concat values
没有。
它们有什么区别?
您的问题是由为链式方法调用提供块时的不同优先级引起的。在您的情况下,您使用以下代码:
qs.concat value.map do |val|
"#{field}=#{val}"
end
Ruby 假定您的意思如下:
qs.concat(value.map) do |val|
"#{field}=#{val}"
end
也就是说,Ruby 将块传递给忽略块的第一个方法(即 qs.concat
)。因为 Array#map
returns an Enumerator
如果你没有通过一个块,你就会得到你看到的错误。
为了解决这个问题,可以使用大括号形式传递块,即:
qs.concat value.map { |val|
"#{field}=#{val}"
}
在这种形式下,块总是传递给 "last" 方法,u.e。你的 map
.
无论如何,如果对运算符的优先级有任何疑问,最好使用显式括号或中间变量来向人类读者和 Ruby 解释器说明如何您的代码应该可以工作。
当你说qs.concat value.map do |val|
时,do
属于什么? (提示:不是 value.map
!)
不确定时使用括号。
qs=["all=true", "limit=-1"]
value=["agent", "service", "token"]
qs.concat(value.map do |val|
"field=#{val}"
end)
{...}
比 do...end
更典型,而且优先级可以计算出来,因此您实际上不需要括号,因为 {...}
会转到 value.map
而不是比 qs.concat
。这也有效:
qs=["all=true", "limit=-1"]
value=["agent", "service", "token"]
qs.concat value.map { |val|
"field=#{val}"
}
我有:
qs = ["all=true", "limit=-1"]
value = ["agent", "service", "token"]
此代码:
qs.concat value.map do |val|
"#{field}=#{val}"
end
最终出现以下错误:
`concat': no implicit conversion of Enumerator into Array (TypeError)`
而这段代码:
values = value.map do |val|
"field=#{val}"
end
qs.concat values
没有。
它们有什么区别?
您的问题是由为链式方法调用提供块时的不同优先级引起的。在您的情况下,您使用以下代码:
qs.concat value.map do |val|
"#{field}=#{val}"
end
Ruby 假定您的意思如下:
qs.concat(value.map) do |val|
"#{field}=#{val}"
end
也就是说,Ruby 将块传递给忽略块的第一个方法(即 qs.concat
)。因为 Array#map
returns an Enumerator
如果你没有通过一个块,你就会得到你看到的错误。
为了解决这个问题,可以使用大括号形式传递块,即:
qs.concat value.map { |val|
"#{field}=#{val}"
}
在这种形式下,块总是传递给 "last" 方法,u.e。你的 map
.
无论如何,如果对运算符的优先级有任何疑问,最好使用显式括号或中间变量来向人类读者和 Ruby 解释器说明如何您的代码应该可以工作。
当你说qs.concat value.map do |val|
时,do
属于什么? (提示:不是 value.map
!)
不确定时使用括号。
qs=["all=true", "limit=-1"]
value=["agent", "service", "token"]
qs.concat(value.map do |val|
"field=#{val}"
end)
{...}
比 do...end
更典型,而且优先级可以计算出来,因此您实际上不需要括号,因为 {...}
会转到 value.map
而不是比 qs.concat
。这也有效:
qs=["all=true", "limit=-1"]
value=["agent", "service", "token"]
qs.concat value.map { |val|
"field=#{val}"
}