Crystal编译器未检测到对象不是nil

问题描述 投票:0回答:1

我有以下课程:

class X
    property son, val
    def initialize(@val : Int32)
        @son = nil.as X?
    end

    def add(other : X?)
        unless other.nil?
            if @son.nil?
                @son = other
            else
                @son.add(other)
            end
        end
    end
end

x = X.new 5
x.add(nil)
x.add(X.new 3)

但是当我尝试build时我会得到

Showing last frame. Use --error-trace for full trace.

In nil-test.cr:12:22

 12 | @son.add(other)
           ^------
Error: undefined method 'include' for Nil (compile-time type is (X | Nil))

根据the manual,这正是编译器应认识到@son分支中的nil不能为else,但显然不能这样做的情况。

我在做什么错?

注意:使用@son.not_nil!.add(other)可行,我只是问为什么编译器不能没有。

crystal-lang
1个回答
0
投票

这仅适用于局部变量,而不适用于实例变量-因为实例变量可能在条件与您访问该变量之间被另一根纤维所突变。请参见Crystal文档中的this section(在“限制”下)。

您可以这样做,将实例变量分配给本地变量,该变量不会在您的身下改变:

def add(other : X?)
  unless other.nil?
    if s = @son
      s.add(other)
    else
      @son = other
    end
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.