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

Nev*_* V. 0 crystal-lang

我有以下课程:

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)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试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))
Run Code Online (Sandbox Code Playgroud)

根据手册,这正是编译器应该识别出@son不能nilelse分支中的情况,但它显然没有这样做。

我究竟做错了什么 ?

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

Wil*_*son 5

这仅适用于局部变量,而不适用于实例变量 - 因为实例变量可能会被条件和您访问变量之间的另一个纤程改变。请参阅Crystal 文档中的此部分(在“限制”下)。

你可以这样做,将实例变量分配给一个不会从你下面改变的局部变量:

def add(other : X?)
  unless other.nil?
    if s = @son
      s.add(other)
    else
      @son = other
    end
  end
end
Run Code Online (Sandbox Code Playgroud)