& 有什么作用?(和号)在 Ruby 中是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36812647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 06:49:07  来源:igfitidea点击:

What does &. (ampersand dot) mean in Ruby?

rubysyntaxoperatorsparameter-passingruby-2.3

提问by Sami

I came across this line of ruby code. What does &.mean in this?

我遇到了这行 ruby​​ 代码。这里面&.是什么意思?

@object&.method

回答by Santhosh

It is called the Safe Navigation Operator. Introduced in Ruby 2.3.0, it lets you call methods on objects without worrying that the object may be nil(Avoiding an undefined method for nil:NilClasserror), similar to the trymethod in Rails.

它被称为安全导航操作员。在 Ruby 2.3.0 中引入,它让您可以调用对象上的方法,而不必担心对象可能是nil(避免undefined method for nil:NilClass错误),类似于tryRails 中方法

So you can write

所以你可以写

@person&.spouse&.name

instead of

代替

@person.spouse.name if @person && @person.spouse

From the Docs:

文档

my_object.my_method

This sends the my_method message to my_object. Any object can be a receiver but depending on the method's visibility sending a message may raise a NoMethodError.

You may use &. to designate a receiver, then my_method is not invoked and the result is nil when the receiver is nil. In that case, the arguments of my_method are not evaluated.

my_object.my_method

这会将 my_method 消息发送到 my_object。任何对象都可以是接收者,但根据方法的可见性,发送消息可能会引发 NoMethodError。

您可以使用 &。指定接收者,则不调用 my_method 并且当接收者为 nil 时结果为 nil。在这种情况下,不评估 my_method 的参数。

回答by Uzbekjon

Note: Even though @Santosh gave a clear and full answer, I would like add some more background and add an important noteregarding its use with non instance variables.

注意:尽管@Santosh 给出了明确而完整的答案,但我想添加更多背景信息并添加有关其与非实例变量一起使用的重要说明



It is called "Safe Navigation Operator" (aka "Optional chaining operator", "Null-conditional operator", etc.). Matz seems to call it "lonely operator". It was introduced in Ruby 2.3. It sends a method to an object only if it is not nil.

它被称为“安全导航运算符”(又名“可选链运算符”、“空条件运算符”等)。Matz 似乎称其为“孤独的运营商”。它是在 Ruby 2.3引入的。仅当它不是时才向对象发送方法nil

Example:

例子:

# Call method `.profile` on `user` only if `user` is not `nil`
@user&.profile

# Equivalent to
unless @user.nil?
  @user.profile
end

"Edge case" with local variables:

带有局部变量的“边缘情况”:

Please note, above code uses instance variables. If you want to use safe navigation operator with local variables, you will have to check that your local variables are defined first.

请注意,上面的代码使用实例变量。如果要对局部变量使用安全导航运算符,则必须先检查是否已定义局部变量。

# `user` local variable is not defined previous
user&.profile

# This code would throw the following error:
NameError: undefined local variable or method `user' for main:Object

To fix this issue, check if your local variable is defined first or set it to nil:

要解决此问题,请检查您的局部变量是否已首先定义或将其设置为 nil:

# Option 1: Check the variable is defined
if defined?(user)
  user&.profile
end

# Option 2: Define your local variable. Example, set it to nil
user = nil
user&.profile     # Works and does not throw any errors

Method background

方法背景

Rails has trymethod that basically does the same. It uses sendmethod internally to call a method. Matz suggestedthat it is slow and this should be a built-in language feature.

Rails 有try基本相同的方法。它在send内部使用方法来调用方法。Matz 建议它很慢,这应该是一个内置的语言功能。

Many other programming languages have similar feature: Objective C, Swift, Python, Scala, CoffeeScript, etc. However, a common syntax is ?.(question dot). But, this syntax could not be adopted by Ruby. Because ?was allowed in method names and thus, ?.symbol sequence is already a valid Ruby code. For example:

许多其他编程语言也有类似的特性:Objective C、Swift、Python、Scala、CoffeeScript 等。但是,一个常见的语法是?.(问题点)。但是,Ruby 无法采用这种语法。因为?在方法名称中是允许的,因此?.符号序列已经是一个有效的 Ruby 代码。例如:

2.even?.class  # => TrueClass

That's why Ruby community had to come up with different syntax. It was an active discussion and different options were considered (.?, ?, &&, etc.). Here is a list of some considerations:

这就是 Ruby 社区必须提出不同语法的原因。这是一个积极的讨论,被认为不同的选项(.??&&等等)。以下是一些注意事项的列表:

u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails

# And finally
u&.profile&.thumbnails

While choosing the syntax, developers looked at different edge cases and the discussion is quite useful to go through. If you want to go through all variants and nuance of the operator, please see this feature introduction discussionon official Ruby issue tracker.

在选择语法时,开发人员查看了不同的边缘情况,讨论非常有用。如果您想了解运算符的所有变体和细微差别,请参阅官方 Ruby 问题跟踪器上的此功能介绍讨论

回答by Thomas Deranek

Be wary! Though the safe navigation operator is convenient it can also be easy to trick yourself into changing your logic with it. I recommend avoiding the use of it in flow control. Example:

警惕!虽然安全导航操作符很方便,但它也很容易欺骗自己改变逻辑。我建议避免在流量控制中使用它。例子:

str = nil

puts "Hello" if str.nil? || str.empty?
# The above line is different than the below line
puts "Hello" if str&.empty?

In the first example, str.nil?returns trueand str.empty?is never called, causing the putsstatement to be executed. In the second example however, str&.empty?returns nilwhich is falsey, and the putsstatement is never executed.

在第一个示例中,str.nil?返回truestr.empty?从不调用,导致puts语句被执行。但是,在第二个示例中,str&.empty?返回的nil是 false,并且该puts语句永远不会执行。

回答by Umut ADALI

it used for nil check, such as in kotlin and swift For example; with Object -> Swift and Kotlin

它用于 nil 检查,例如在 kotlin 和 swift 中;使用对象 -> Swift 和 Kotlin

model = car?.model

this model can be nil(Swift) or null(Kotlin) if we have not defined the model value in car class. we use that ampersand instead of question mark in ruby

如果我们没有在汽车类中定义模型值,这个模型可以是 nil(Swift) 或 null(Kotlin)。我们在 ruby​​ 中使用那个和号而不是问号

model = car&.model

if use car.model without ampersand and if model is nil the system cannot continue running.

如果使用没有 & 符号的 car.model 并且模型为零,则系统无法继续运行。