我有一个关于 ruby 中 ||= 语句的问题,这对我特别感兴趣,因为我正在使用它写入内存缓存。我想知道的是, ||= 首先检查接收器,看看它在调用该设置器之前是否已设置,或者它实际上是一个别名x = x || y
对于普通变量来说这并不重要,但使用类似以下内容:
CACHE[:some_key] ||= "Some String"
可能会进行内存缓存写入,这比简单的变量集更昂贵。奇怪的是,我在 ruby api 中找不到任何关于 ||= 的内容,所以我自己无法回答这个问题。
我当然知道:
CACHE[:some_key] = "Some String" if CACHE[:some_key].nil?
为了实现这一点,我只是在寻找最简洁的语法。
这非常容易测试:
class MyCache
def initialize
@hash = {}
end
def []=(key, value)
puts "Cache key '#{key}' written"
@hash[key] = value
end
def [](key)
puts "Cache key '#{key}' read"
@hash[key]
end
end
现在只需尝试一下||=
syntax:
cache = MyCache.new
cache["my key"] ||= "my value" # cache value was nil (unset)
# Cache key 'my key' read
# Cache key 'my key' written
cache["my key"] ||= "my value" # cache value is already set
# Cache key 'my key' read
因此我们可以得出结论,如果缓存键已经存在,则不会进行任何分配。
以下摘自 Rubyspecshows http://github.com/rubyspec/rubyspec/blob/master/language/variables_spec.rb这是按设计并且不应依赖于 Ruby 实现:
describe "Conditional operator assignment 'obj.meth op= expr'" do
# ...
it "may not assign at all, depending on the truthiness of lhs" do
m = mock("object")
m.should_receive(:foo).and_return(:truthy)
m.should_not_receive(:foo=)
m.foo ||= 42
m.should_receive(:bar).and_return(false)
m.should_not_receive(:bar=)
m.bar &&= 42
end
# ...
end
在同一个文件中,有一个类似的规范[]
and []=
这要求相同的行为。
尽管 Rubyspec 仍在进行中,但很明显,主要的 Ruby 实现项目都打算遵守它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)