ruby - 双管有没有实际区别|| 和 Ruby 中的单例?
问题描述
昨天我在阅读有关 Ruby 的文章并达到了 Singleton 的概念,其中提到用于避免多次实例化一个类。
我以前不知道这个概念,但是当我想达到这个目的时,我正在创建一个全局变量并使用双管道 || 反而。
例如:
@browser ||= Browser.new
在某些情况下是否有任何区别或优势可以更好地使用 Singleton?
解决方案
||=
用于记忆一个值。例如,如果您有一个方法执行昂贵的操作或返回一个变化的值:
class Foo
def now
Time.now
end
end
f = Foo.new
f.now #=> 2018-06-21 11:59:56 +0200
f.now #=> 2018-06-21 11:59:59 +0200
f.now #=> 2018-06-21 12:00:02 +0200
您想缓存该值,||=
是您的朋友:
class Foo
def now
@now ||= Time.now
end
end
f = Foo.new
f.now #=> 2018-06-21 11:59:56 +0200
f.now #=> 2018-06-21 11:59:56 +0200
f.now #=> 2018-06-21 11:59:56 +0200
第一次调用调用Time.now
并将结果分配给@now
. 随后的调用只是返回@now
而不评估右侧。因此,Time.now
只被调用一次,方法的返回值不再改变。
并且因为@now
是一个实例变量,所以每个实例都存储一个单独的值:
f = Foo.new
f.now #=> 2018-06-21 11:59:56 +0200
f.now #=> 2018-06-21 11:59:56 +0200
f.now #=> 2018-06-21 11:59:56 +0200
g = Foo.new
f.now #=> 2018-06-21 12:00:02 +0200
f.now #=> 2018-06-21 12:00:02 +0200
f.now #=> 2018-06-21 12:00:02 +0200
另一方面,单例确保给定类(每个进程)有一个(并且只有一个)实例,例如:
require 'singleton'
class Foo
include Singleton
def now
@now ||= Time.now
end
end
f = Foo.instance
f.now #=> 2018-06-21 11:59:56 +0200
f.now #=> 2018-06-21 11:59:56 +0200
g = Foo.instance
g.now #=> 2018-06-21 11:59:56 +0200
g.now #=> 2018-06-21 11:59:56 +0200
那是因为f
andg
指的是同一个对象。包括Singleton
删除通过new
or创建任何其他实例的能力allocate
:
Foo.new #=> NoMethodError
Foo.allocate #=> NoMethodError
推荐阅读
- java - 使用 SimpleDateFormat 格式化日期时抛出 ClassCastException
- c# - 从android java返回字节数组引用到csharp unity
- json - 如何从嵌套的json中提取键值对
- unreal-engine4 - UE4:仍然生成对象,即使我将其设置为“不生成”
- scala - 如何将 Free monad 转换为 Free applicatives
- python - 如何将本地保存的图像添加到 python 中的绘图图形?
- javascript - 它作为组合值传递 4,5,6
- haskell - GHC 多包版本警告的严重性
- ssis - 将可变长度记录解析为表列,其中特定列在 SSIS 2016 中是动态的
- c# - 如何从 azure 函数获取 json 对象的输出?