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

Crystal compiler does not detect that object is not nil

我有以下 class :

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 不能在 else 分支中成为 nil 的情况,但显然没有这样做。

我做错了什么?

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

这仅适用于局部变量,不适用于实例变量 - 因为实例变量可能会在条件和您访问变量之间被另一个光纤改变。请参阅 Crystal 文档中的 this section(在 "Limitations" 下)。

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

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