"undefined method 'zero' for Nil:Class" when #sum the Array without Nils
"undefined method 'zero' for Nil:Class" when #sum the Array without Nils
当构建数组的变量最初是 nil
时会出现此问题。
y = (1..2).map do
v = nil
v = 1
v
end
p y # => [1, 1]
p y.class # => Array(Int32)
p y.sum # => 2
当 v
在某个条件下停止 nil
时,这可能是计算性的,并且在编译时无法解决:
z = (1..2).map do
v = nil
v = 1 if true
v
end
p z # [1, 1]
p z.class # => Array(Nil | Int32)
数组变得更复杂,与当前 sum
实现不兼容,因此 p z.sum
导致编译时错误:
undefined method 'zero' for Nil:Class (compile-time type is (Nil | Int32):Class)
def sum(initial = T.zero)
^~~~
我该如何正确应对?
或者它可能等待 stdlib sum
方法或其他任何更好的实现?
UPD:inject
给出相同的:
p z.inject{ |i, j| i + j }
undefined method '+' for Nil (compile-time type is (Nil | Int32))
您可以使用 Iterator#compact_map
到 select 非零值。在这种情况下,编译器将能够推断出 Array(Int32)
。
http://play.crystal-lang.org/#/r/e85
z = (1..2).map do
v = nil
v = 1 if true
v
end
pp typeof(z) # => Array(Nil | Int32)
pp z # => z = [1, 1]
y = z.compact_map(&.itself)
pp typeof(y) # => Array(Int32)
pp y # => y = [1, 1]
另外,请注意 typeof(Expr)
和 Expr.class
可能会导致不同的结果。第一个是编译时类型,后面是运行时类型。
Brian 所说的另一种解决方案是将 sum
与块一起使用:
http://play.crystal-lang.org/#/r/ein
z = (1..2).map do
v = nil
v = 1 if true
v
end
puts z.sum { |x| x || 0 } #=> 2
当构建数组的变量最初是 nil
时会出现此问题。
y = (1..2).map do
v = nil
v = 1
v
end
p y # => [1, 1]
p y.class # => Array(Int32)
p y.sum # => 2
当 v
在某个条件下停止 nil
时,这可能是计算性的,并且在编译时无法解决:
z = (1..2).map do
v = nil
v = 1 if true
v
end
p z # [1, 1]
p z.class # => Array(Nil | Int32)
数组变得更复杂,与当前 sum
实现不兼容,因此 p z.sum
导致编译时错误:
undefined method 'zero' for Nil:Class (compile-time type is (Nil | Int32):Class)
def sum(initial = T.zero)
^~~~
我该如何正确应对?
或者它可能等待 stdlib sum
方法或其他任何更好的实现?
UPD:inject
给出相同的:
p z.inject{ |i, j| i + j }
undefined method '+' for Nil (compile-time type is (Nil | Int32))
您可以使用 Iterator#compact_map
到 select 非零值。在这种情况下,编译器将能够推断出 Array(Int32)
。
http://play.crystal-lang.org/#/r/e85
z = (1..2).map do
v = nil
v = 1 if true
v
end
pp typeof(z) # => Array(Nil | Int32)
pp z # => z = [1, 1]
y = z.compact_map(&.itself)
pp typeof(y) # => Array(Int32)
pp y # => y = [1, 1]
另外,请注意 typeof(Expr)
和 Expr.class
可能会导致不同的结果。第一个是编译时类型,后面是运行时类型。
Brian 所说的另一种解决方案是将 sum
与块一起使用:
http://play.crystal-lang.org/#/r/ein
z = (1..2).map do
v = nil
v = 1 if true
v
end
puts z.sum { |x| x || 0 } #=> 2