我正在读this。使用此方法有什么好处:

user&.address&.state

过度
user.try(:address).try(:state)

我还是不明白。

最佳答案

(1)&.通常比try(...)

根据情况,这可以使您的代码更具可读性。

(2)&.是标准Ruby,而不是trytry方法未在Ruby核心库中定义,而是在Rails库中定义。当您不是在开发RoR网络应用程序,而是在编写例如小 helper 脚本,这将很快变得相关。
(例如,与Bash相比,我更喜欢Ruby。)

(3)&.使调试更容易

如果正在调用不存在的方法,则安全遍历运算符将引发错误。

>> "s"&.glubsch
NoMethodError: undefined method `glubsch' for "s":String

仅在nil上,它的行为会宽松:
>> nil&.glubsch
=> nil
try方法将始终返回nil
>> "s".try(:glubsch)
=> nil

请注意,最新版本的Ruby和Rails就是这种情况。

现在,假设存在一种名为glubsch的方法。然后,您决定重命名该方法,但是忘记在一处重命名它。 (不幸的是,这可能是在ruby中发生的。。。)使用安全的遍历运算符,您几乎会立即注意到该错误(第一次执行该行代码时)。但是,try方法将很乐意为您提供nil,并且您会在程序执行的下游某处得到与nil相关的错误。有时很难弄清楚这种nil的来源。

&.盲目地返回nil相比,try的快速失败使调试变得更加容易。

编辑:在这方面,还有与try!相同的变体&.(带有爆炸声)。如果您不喜欢&.,请使用它。

(4)如果我不在乎某个方法是否实现,该怎么办?

那太奇怪了。由于这将是一种意外的编程方式,因此请使其明确。例如,通过使用respond_to?充实这两种情况(无论是否实现),然后分支出去。

(5)try的块形式如何?

除了方法名,还可以将一个块传递给try。该块将在接收者的上下文中执行;并且在该块内没有应用宽大处理。因此,只需一个方法调用,它的行为就与&.相同。
>> "s".try{ glubsch }
NameError: undefined local variable or method `glubsch' for "s":String

对于更复杂的计算,您可能更喜欢这种块形式而不是引入很多局部变量。例如。一连串的
foo.try{ glubsch.blam }.try{ bar }.to_s

将允许foonil,但需要foo.glubsch返回非nil值。再一次,您可以以更简洁的方式使用安全遍历运算符执行相同的操作:
foo&.glubsch.blam&.bar.to_s

但是,使用try的块形式进行复杂的计算恕我直言是一种代码味道,因为它妨碍了可读性。当您需要实现复杂的逻辑时,请使用描述性名称引入局部变量,并可能使用if分支出nil案例。您的代码将更具可维护性。

HTH!

10-05 20:31
查看更多