3

我在使用 index.js 时发现了一些奇怪的行为。

#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

我得到错误:

没有重载匹配 'Array(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

我明白。它可能是 nil,但由于我已经在检查它是否为 nil,所以这里应该没有问题。我在想前面的代码片段遇到了同样的问题。

4

4 回答 4

3

问题是 Array#index 是可空的;它可能找不到任何东西并返回 nil,因此它返回一个 Int32|Nil 联合。

编译器最终会失败,因为 Array#[] 需要一个 Int32 参数,但我们将它传递给了一个 Int32|Nil。例如,您必须通过检查返回值是否为真来处理这种情况(以避免以后的错误)。

于 2016-11-21T12:38:17.527 回答
1

正如@julien-portalier 所述:

问题是 Array#index 是可空的;它可能在数组中找不到任何东西并返回 Nil,因此它返回一个 (Int32 | Nil) 联合。

您可以使用Object#not_nil!获得 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#indexis not 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
于 2016-11-24T13:43:01.763 回答
0

更好的方法是使用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
于 2016-11-20T18:55:39.600 回答
0

我只是这样做:

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

这样只会返回 int 值,不返回 nil。它似乎工作正常。

于 2016-11-19T18:36:41.440 回答