ruby 运算符 ||= 智能吗?

2024-05-04

我有一个关于 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(使用前将#替换为@)

ruby 运算符 ||= 智能吗? 的相关文章

随机推荐