首页 文章

Crystal没有超载匹配'Array(Type)#[]'与类型(Int32 | Nil)

提问于
浏览
2

我在使用索引时发现了一些奇怪的行为 .

#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

我收到错误:

没有重载匹配'数组(类型)#[]'与类型(Int32 | Nil)

不确定为什么索引不起作用,因为index = 0 .

编辑:

更多信息 . 如果我这样做:

if index == nil
  #Do something
#error => undefined method '>=' for Nil (compile-time type is (Int32 | Nil))
elsif index >= 0
  #Do something else
end

我明白了它可能是零,但因为我已经检查它是否为零,所以这里不应该有问题 . 我认为以前的代码片段遇到了同样的问题 .

4 回答

  • 3

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

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

  • 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值,没有nils . 它似乎工作正常 .

  • 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
    
  • 0

    正如@ 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#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
    

相关问题