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
我有以下 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