我们啥时候在 Rails 中使用 "||=" 运算符?它的意义是啥? [复制]
Posted
技术标签:
【中文标题】我们啥时候在 Rails 中使用 "||=" 运算符?它的意义是啥? [复制]【英文标题】:When do we use the "||=" operator in Rails ? What is its significance? [duplicate]我们什么时候在 Rails 中使用 "||=" 运算符?它的意义是什么? [复制] 【发布时间】:2011-08-07 04:14:57 【问题描述】:可能重复:What does the operator ||= stands for in ruby?
我对 Rails 中 ||=
运算符的使用感到困惑。我在网上找不到任何有用的东西。谁能指导一下?
如果有任何您知道的网络链接,请告诉我。
我想知道以下语句的含义:
@_current_user ||= session[:current_user_id] &&
User.find(session[:current_user_id])
【问题讨论】:
这不是“Rails”,而是标准的 Ruby 运算符。 @the Tin Man - 我同意。谢谢。 【参考方案1】:首先在 C 中流行,二元运算符的简写,例如:
a += b # and...
a ||= b
表现得像:
a = a + b # and ... note the short circuit difference ...
a || a = b
重新安排更有效的短路是处理 nil 检查的一种优雅方式,因为它可以完全避免分配。分配可能有副作用。这只是 Ruby 中经过深思熟虑的设计的另一个例子。
请参阅http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html 以获得更冗长的解释。
【讨论】:
-1。这个答案实际上并不正确。a ||= b
不等于 a = a || b
。请参阅rubyinside.com/… 甚至接受的答案。这是一个普遍的误解。接受的答案实际上是正确的答案。 a ||= b
等价于a || a = b
,即如果a
不是falsy(false
或nil
),则将a
设置为b
的值。跨度>
^^^ Muphry's law 的经典案例。我的意思是:如果a
是假的(false
或nil
),那么将a
设置为b
的值。
很好,我现在了解了Muphry's Law, 呵呵。答案固定。【参考方案2】:
如果您有 C# 经验,我相信它与 C# 中的 null-coalescing (??) 运算符类似(但更多的是 Ruby 技巧)
int? y = x ?? -1
如果 x 不为 null,则将 x 分配给 y,否则使用“默认”值 -1。
同样,||= 被称为 T 方运算符,我相信。
a || = b
或
a || a = b
发表你的声明
@_current_user ||= session[:current_user_id] &&
User.find(session[:current_user_id])
基本上,它会查看 @_current_user 是否为 nil。如果它有一些价值,不要管它(当前用户。)否则,使用用户 ID 从会话中获取当前用户。它首先查看 id 是否在会话中,然后从用户那里获取。
有关“T-square”运算符的更多信息,请查看以下博客:
http://blogs.oracle.com/prashant/entry/the_ruby_t_square_operator
【讨论】:
【参考方案3】:让我们分解一下:
@_current_user ||= SOMETHING
这就是说,如果 nil
、false
或未定义,请将 @_current_user
设置为 SOMETHING
。否则将其设置为@_current_user
,或者换句话说,什么也不做。扩展形式:
@_current_user || @_current_user = SOMETHING
好的,现在到右侧。
session[:current_user_id] &&
User.find(session[:current_user_id])
您通常会看到 &&
仅具有布尔值,但在 Ruby 中您不必这样做。这里的技巧是,如果session[:current_user_id]
不为零,并且User.find(session[:current_user_id])
不为零,则表达式将计算为User.find(session[:current_user_id])
,否则为nil。
所以把它们放在伪代码中:
if defined? @_current_user && @_current_user
@_current_user = @_current_user
else
if session[:current_user_id] && User.find(session[:current_user_id])
@_current_user = User.find(session[:current_user_id])
else
@_current_user = nil
end
end
【讨论】:
谢谢迈克。这样就很清楚了。 很高兴我能帮助@mad.geek。祝你好运 :) 请记住,如果您觉得这似乎正确回答了您的问题,请确保将其标记为正确。 学究起来,a ||= b
其实就相当于a || a = b
。
如果您使用布尔值作为变量的数据类型,请注意不要将其放入 rails after_initialize 方法。因为如果您尝试在 after_initialize 中使用变量 ||= true 将默认值设置为 true,它将几乎总是将变量设置为 true。我这样做并浪费了 2 天时间来查找错误,因为我认为只有当 nil 是对象进入 after_initialize 时变量具有的值时,它才会将值设置为 true。
@ReinHenrichs 不是a = a || b
吗?【参考方案4】:
这是缓存能力。
a ||= 1 # a assign to 1
a ||= 50 # a is already assigned, a will not be assigned again
puts a
#=> 1
这在你从数据库加载当前用户时很有用,如果这是之前加载的,语句将不会尝试评估等式的正确部分,即 DRY,因此你可以将其视为缓存运算符。
参考: http://railscasts.com/episodes/1-caching-with-instance-variables
【讨论】:
以上是关于我们啥时候在 Rails 中使用 "||=" 运算符?它的意义是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
我们啥时候应该在 Xcode 中使用“嵌入式二进制文件”而不是“链接框架”?