下面的代码在Ruby中是什么意思?

||=

它的语法有什么意义或原因吗?


当前回答

||=是一个条件赋值运算符

  x ||= y

等于

  x = x || y

或者

if defined?(x) and x
    x = x
else 
    x = y
end

其他回答

它的意思是或等于。它检查左边的值是否有定义,然后使用它。如果不是,使用右边的值。您可以在Rails中使用它来缓存模型中的实例变量。

一个基于rails的快速示例,我们创建了一个函数来获取当前登录的用户:

class User > ActiveRecord::Base

  def current_user
    @current_user ||= User.find_by_id(session[:user_id])
  end

end

它检查是否设置了@current_user实例变量。如果是,它将返回该值,从而节省数据库调用。但如果没有设置,则执行调用,然后将@current_user变量设置为该值。这是一种非常简单的缓存技术,但非常适合在应用程序中多次获取相同的实例变量。

A ||= b和A = b是一样的如果A。nil?或者a = b,除非a

但是所有3个选项都能显示相同的性能吗?在Ruby 2.5.1中

1000000.times do
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
end

在我的电脑上花费0.099秒,而

1000000.times do
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
end

用时0.062秒。这几乎快了40%。

然后我们还有:

1000000.times do
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
end

这需要0.166秒。

并不是说这将在一般情况下产生重大的性能影响,但是如果您确实需要最后一点优化,那么可以考虑这个结果。 顺便说一下:a = 1,除非a对新手来说更容易理解,否则它是不言自明的。

注1:重复分配行多次的原因是为了减少循环在测量时间上的开销。

注2:如果我在每次赋值前执行a=nil,结果是类似的。

||=是一个条件赋值运算符

  x ||= y

等于

  x = x || y

或者

if defined?(x) and x
    x = x
else 
    x = y
end

简洁完整的回答

a ||= b

计算方法与下面每一行相同

a || a = b
a ? a : a = b
if a then a else a = b end

-

另一方面,

a = a || b

计算方法与下面每一行相同

a = a ? a : b
if a then a = a else a = b end

-

编辑:正如AJedi32在评论中指出的那样,这只在以下情况下成立:A是一个已定义变量。2. 计算一次时间和两次时间不会导致程序或系统状态的差异。

这是默认的赋值表示法

例如:x ||= 1 这将检查x是否为nil。如果x确实为nil,那么它就会赋给它一个新值(在我们的例子中是1)

更明确的表示: 如果x == nil X = 1 结束