此逻辑AND运算符的作用是什么?

问题描述

在/rails/lib/rails.rb中,有一个用逻辑&&运算符的习惯用法:

def root
  application && application.config.root
end

这个成语是什么意思?似乎有一些控制流程,如果应用程序存在或类似的东西,只返回application.config.root?

解决方法

在ruby中,逻辑运算符是“惰性”。

请考虑以下内容:

def one
  puts "Called method one"
  false
end

def two
  puts "Called method two"
  true
end

puts "Calling one,then two:"
one && two

puts
puts "Calling two,then one:"
two && one

它给出以下输出:

Calling one,then two:
Called method one

Calling two,then one:
Called method two
Called method one

看看发生了什么事?当它调用one并得到false时,它根本不费心调用方法two-因为它已经知道最终结果将是{{ 1}}。 (false == false && false == false && true。)

现在让我们回顾一下您发布的原始代码:

false

如果def root application && application.config.root end 会怎样?这段代码根本不用费心评估右侧。自application == nil起。

换句话说,这是一种安全措施。如果nil && literally_anything == nil,则可以防止代码失败。它(不是完全,而是基本上)等同于编写以下代码:

application == nil
,

避免NoMethodError

在对计算结果为nil的表达式或不#respond_to吗的对象上调用方法时,Ruby代码会引发NoMethodError。一种特定的方法。较新版本的Ruby支持safe navigation operator来防止在NilClass实例上调用方法,而较早的代码通常需要这种类型的构造以避免引发异常。

在伪代码中:

define method "root":
  if application does not evaluate to nil,then
    invoke method config on application,then
      invoke method root on application.config

在Ruby> = 2.3中,您可能将此方法重写为:

def root
  application&.config.root
end

但是,在某些情况下,&.并不完全等同于obj && obj.method。前者只是防止在nil上调用方法。例如,如果application.nil?application.respond_to? :config均为假,则在调用application&.config时使用安全导航器仍会引发异常。

由于设置或使用了 application 变量的方式,是否需要在示例中进行逻辑AND操作,您还是希望保留传统习语或为了与Ruby早期版本向后兼容而保留必须在Rails代码库中进行调查。在任何情况下,示例中的逻辑AND均防止NoMethodError异常。

,

根据广泛使用的红宝石样式指南https://github.com/rubocop-hq/ruby-style-guide#if-as-a-modifier,当您使用单行正文时,需要偏爱使用修饰符if/unless。另一个不错的选择是使用控制流&&/||(即您要问的内容)。

# bad
if some_condition
  do_something
end

# good
do_something if some_condition

# another good option
some_condition && do_something

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...