我得到了
undefined method 'start_time' for Nil (compile-time type is (Reservation | Nil))
代码
if game.reservation && other_game.reservation
if(game.reservation.start_time == other_game.reservation.start_time)
return false
end
end
但如果我这样做
reservation : Reservation | Nil = game.reservation
other_reservation : Reservation | Nil = other_game.reservation
if reservation && other_reservation
if(reservation.start_time == other_reservation.start_time)
return false
end
end
为什么这些表达不等同?通常,if是一个类型过滤器,它从类型中删除Nil
联合,但不是在它是嵌套对象时。第二种方式有效,但感觉不必要地冗长。
在嵌套对象上使用if执行类型过滤器的正确方法是什么?
答案 0 :(得分:3)
让我们稍微简化一下(它仍然是同样的错误):
if game.reservation
game.reservation.starting_time
end
条件确保game.reservation
的返回值不是nil
。此表达式只是在reservation
上调用方法game
。之后不会重用返回的值,并且无法知道对同一方法的第二次调用是否可能返回nil
。
您可以通过将返回值存储在局部变量中来轻松解决此问题。这样编译器可以确定它的值不是nil
。这甚至更高效,因为它节省了(可能代价高昂的)对同一方法的额外调用。
if reservation = game.reservation
reservation.starting_time
end
语言参考中详细解释了确切的行为:https://crystal-lang.org/docs/syntax_and_semantics/if_var.html