Что делает &. (амперсанд точка) значит в Рубине?



я наткнулся на эту строку кода ruby. Что значит &. значит в этом?



@object&.method
711   3  

3 ответов:

он называется оператором безопасной навигации. Введенный в Ruby 2.3.0, он позволяет вызывать методы на объектах, не беспокоясь о том, что объект может быть nil(избегая undefined method for nil:NilClass ошибка), аналогично try метод в Rails.

так что вы можете написать

@person&.spouse&.name

вместо

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

С Docs:

my_object.my_method

это отправляет сообщение my_method в my_object. Любой объект может быть приемником, но в зависимости от видимости метода отправка сообщения может вызвать NoMethodError.

вы можете использовать &. назначить приемника, то заканчивается не вызывается и результат равен нулю, когда приемник равен нулю. В этом случае доводы заканчивается не оцениваются.

Примечание: хотя @Santosh дал четкий и полный ответ, я хотел бы добавить еще немного фона и добавить важное замечание относительно его использования с переменными без экземпляра.


это называется "Оператор Безопасной Навигации" (aka "необязательный оператор цепочки", "нулевой условный оператор" и т. д.). МАЦ, кажется, называет его "одиноким оператором". Это было введено в Ruby 2.3. Он отправляет метод к объекту только если это не nil.

пример:

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

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

"крайний случай" с локальными переменными:

обратите внимание, что приведенный выше код использует переменные экземпляра. Если вы хотите использовать оператор безопасной навигации с локальными переменными, вам нужно будет сначала проверить, определены ли ваши локальные переменные.

# `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

чтобы устранить эту проблему, проверьте, определена ли ваша локальная переменная первой или установите ее в 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

способ фон

рельсов try метод, который в основном делает то же самое. Он использует send метод внутренне для вызова метода. Матц предложил что это медленно и это должно быть встроенной функцией языка.

многие другие языки программирования имеют аналогичную функцию: Objective C, Swift, Python, Scala, CoffeeScript и т. д. Однако общим синтаксисом является ?. (точка вопрос). Но этот синтаксис не может быть принят Руби. Потому что ? было разрешено в имена методов и, таким образом, ?. последовательность символов уже является допустимым кодом Ruby. Например:

2.even?.class  # => TrueClass

вот почему сообщество Ruby должно было придумать другой синтаксис. Это было активное обсуждение и рассматривались различные варианты (.?,?,&& и т. д.). Вот список некоторых соображений:

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

# And finally
u&.profile&.thumbnails

при выборе синтаксиса разработчики посмотрели на разные крайние случаи,и обсуждение довольно полезно пройти. Если вы хотите пойти через все варианты и нюансы оператора, пожалуйста, смотрите эта функция введение обсуждение на официальном трекере Ruby.

будьте осторожны! Хотя оператор безопасной навигации удобен, также может быть легко обмануть себя, изменив свою логику с его помощью. Я рекомендую избегать использования его в управлении потоком. Пример:

str = nil

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

в первом примере, str.nil? возвращает true str.empty? никогда не вызывается, причинив puts инструкция для выполнения. Во втором примере, однако, str&.empty? возвращает nil, который является falsey, и puts утверждение не выполняется.

Comments

    Ничего не найдено.