晶体无过载符合类型(Int32 |无)的'Array(Type)#[]'
使用索引时,我发现一些奇怪的行为。晶体无过载符合类型(Int32 |无)的'Array(Type)#[]'
#Defined in the class's initialize
@my_list = [] of Type
index = @my_list.index { |i| i.value == 2 } # => 0
@my_list[0] # => 2
@my_list[index] # => error
我得到的错误:
no overload matches 'Array(Type)#[]' with type (Int32 | Nil)
不知道为什么指数是不行的,因为指数= 0
编辑:
更多信息。如果我这样做:
if index == nil
#Do something
#error => undefined method '>=' for Nil (compile-time type is (Int32 | Nil))
elsif index >= 0
#Do something else
end
我明白。这可能是零,但由于我已经检查,看它是否为零,这里应该没有问题。我在想以前的代码片段正在运行到相同的问题。
我只是要做到这一点:
def get_index(val)
i = 0
while i < @my_list.size
if @my_list[i].value == val
return i
end
i += 1
end
return -1
end
这样,只有国际价值将被退回,没有尼尔斯。它似乎工作正常。
更好的办法是使用times
方法它更简单,更清晰:
def get_index(val)
@my_list.size.times do |i|
return i if @my_list[i] == val
end
-1
end
UPD
或多个简单
def get_index(val)
@my_list.index { |value| value == val } || -1
end
的问题是,数组#指数nilable;它可能找不到任何东西并返回nil,因此它返回一个Int32 | Nil联合。
编译器最终失败,因为Array#[]需要一个Int32参数,但我们将其传递给Int32 | Nil。例如,您必须通过检查返回值是否真实来关注这种情况(以避免后来的错误)。
如前所述通过@朱利安 - portalier:
The problem is that Array#index is nilable; it may not find anything in the array and return Nil, hence it returns an (Int32 | Nil) union.
您可以使用Object#not_nil!来获得无类型的骑:
@my_list = [2, 4, 6, 8]
index = @my_list.index { |i| i == 6 }.not_nil! # => 2
# compile type of 'index' is Int32
@my_list[0] # => 2
@my_list[index] # => 6
它将确保通过Array#index
返回的类型不是Nil
如果是,则会产生异常(参见Nil#not_nil!)
如果你需要处理的索引错误,而不使用异常,你可以简单地检查是否Array#index
失败:
@my_list = [2, 4, 6, 8]
index = @my_list.index { |i| i == 6 } # => 2
# compile-time type of 'index' is (Int32 | Nil)
if index
# In this scope, compile-time type of 'index' is Int32
@my_list[0] # => 2
@my_list[index] # => 6
end