嵌套Crystal对象

时间:2018-02-10 20:18:45

标签: crystal-lang

我得到了

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执行类型过滤器的正确方法是什么?

1 个答案:

答案 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