Ruby 中的 `try` 和 `&.`(安全导航运算符)有什么区别

What is the difference between `try` and `&.` (safe navigation operator) in Ruby

这是我的代码:

class Order < Grape::Entity
  expose :id { |order, options| order.id.obfuscate }
  expose :time_left_to_review do |order, options|
    byebug
    order&.time_left_to_review # ERROR
  end
  expose :created_at { |order, options| order.last_transition.created_at }
end

# NoMethodError Exception: undefined method `time_left_to_review' for #<Order:0x007f83b9efc970>

我以为 &..try 的快捷方式,但我想我错了。有人可以指出我所缺少的正确方向吗?

我觉得这与 ruby 无关。也许是葡萄?虽然我不明白这是怎么回事。

try 方法忽略了很多事情,它只是试一试,如果事情不成功就收工。

& 条件导航选项将 阻止对nil 对象的调用。任何其他内容均被视为有效,并将承担全部后果,包括例外情况。

&. 的工作方式类似于 #try!,而不是 #try

这里是 #try! 的描述(来自 documentation):

Same as #try, but will raise a NoMethodError exception if the receiving is not nil and does not implemented the tried method.

所以基本上它可以避免您在 nil 上调用方法,但是如果出现一个对象,它会像往常一样尝试调用它的方法。

引用自Rails文档,所以强调一下很重要 Ruby 不提供 #try;它由 Rails 或更准确地说是 ActiveSupport 提供。然而,safe navigation operator (&.) 是 Ruby 2.3.0.

中提供的语言功能

我来这里有点晚了,其他答案已经涵盖了它是如何工作的,但我想补充一些其他答案没有涵盖的内容。

您的问题是 Ruby 中的 try&. 有什么区别。 Ruby 是这里的关键词。

最大的区别是Ruby中没有try,它是Rails提供的方法。如果您在 rails 控制台中执行类似操作,您可以看到这个或您自己:

[1, 2, 3].try(:join, '-')
#=> "1-2-3" 

然而,如果您在 irb 控制台中执行相同的操作,您将得到:

[1, 2, 3].try(:join, '-')
NoMethodError: undefined method `try' for [1, 2, 3]:Array

&. 是 Ruby 标准库的一部分,因此可用于任何 Ruby 项目,而不仅仅是 Rails。

除了上述答案外,我正在添加一些示例。1

account = Account.new(owner: Object.new)

account.try(:owner).try(:address)
# => nil

account&.owner&.address
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`

account.try!(:owner).try!(:address)
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`

正如我们所见,try 不检查接收者是否响应给定的方法。而 try!&. 的行为相同。如果接收方响应 address 方法,则所有接收方都会 return 相同的结果。我更喜欢使用 &.,因为它看起来更干净。

有关安全导航运算符 (&.) 的更多信息,我发现此博客非常有用 https://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/