我对ruby中的OR EQUALS(||=
)运算符有些怀疑。 ruby解释器如何实现它?以下是代码示例:
class C
def arr
@num ||= []
end
end
当我们在这种情况下使用OR EQUALS运算符时,第一次调用此方法会初始化变量并添加一个元素,这很好。当第二次调用arr
时,它如何知道该数组中有一个元素..
答案 0 :(得分:3)
在Ruby中,有两个值被视为逻辑错误。第一个是布尔值false
,另一个是nil
。任何非nil
且未明确false
的内容都是true
。第一次通过该方法,@num
为nil
,被视为false
,or
的{{1}}部分需要进行评估并最终结束将空数组分配给||=
。由于现在不是@num
,它等同于nil
。由于true
无论true || x
是什么都是正确的,因此在将来的调用中,Ruby会使评估短路并且不会进行分配。
答案 1 :(得分:0)
一般来说,x ||= y
相当于x = x || y
,它只是简写。它是作为展开式表单实现的,与&&=
,+=
或-=
相同。
包含Ruby的大多数编程语言将停止在遇到的第一个 true 值上执行像||
这样的逻辑比较语句并返回该语句。同样,使用&&
时,它将停止在第一个 false 值。
一般而言:
false || FOO()
这将返回false
而不是评估foo()
。
该模式最好被描述为“延迟初始化器”,即变量仅定义一次,但仅在实际使用时定义。这与“渴望初始化程序”形成对比,“初始化程序”会尽可能早地完成,例如initialize
方法内部。
您将看到此模式的其他版本,例如:
def arr
@num ||= begin
stuff = [ ]
# ...
stuff
end
end
这可以处理初始值不是很简单并且可能需要一些工作来生成的情况。再一次,它只是在第一次调用方法时才生成。
Ruby如何知道第二遍不再初始化它?很简单,到那时@num
已被定义为某种东西。
请注意,如果您使用的false
值会被评估为非真值,那么每次都会触发||=
。 Ruby中唯一两个逻辑错误的值是nil
和false
,因此大多数情况下这不是问题。
如果您还需要处理false
,则必须以长篇方式执行此操作:
def arr
return @num unless num.nil?
@num = false
end
有人提到添加||=
- 类似的运算符只能在nil
上触发,但我认为它还没有被添加到Ruby中。