晶体无过载符合类型(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