使用new运算符定义对象与通过扩展类定义独立对象之间的区别是什么?斯卡拉 - 新的vs对象扩展
更具体而言,给定类型class GenericType { ... }
,val a = new GenericType
和object a extends GenericType
之间的区别是什么?
使用new运算符定义对象与通过扩展类定义独立对象之间的区别是什么?斯卡拉 - 新的vs对象扩展
更具体而言,给定类型class GenericType { ... }
,val a = new GenericType
和object a extends GenericType
之间的区别是什么?
作为一个实际问题,object
声明初始化为相同的机制如在字节码new
。但是,有很多不同之处:
object
作为单例 - 每个属于只有一个实例存在的类;object
被延迟初始化 - 它们只会在首次引用时被创建/初始化;object
和class
(或trait
)的相同名称是伴侣;object
上的方法在伴侣class
上生成静态转发器;object
的成员可以访问伙伴class
的私人成员;这些只是我能想到的蝙蝠权利的一些差异。可能还有其他人。
*什么是“相关”类或性状是一个更长的故事 - 查找堆栈溢出问题,如果你有兴趣解释它。如果您无法找到它们,请查看scala
标记的维基。
对象定义(无论它是否扩展)意味着创建单例对象。
scala> class GenericType
defined class GenericType
scala> val a = new GenericType
a: GenericType = [email protected]
scala> val a = new GenericType
a: GenericType = [email protected]
scala> object genericObject extends GenericType
defined module genericObject
scala> val a = genericObject
a: genericObject.type = [email protected]
scala> val a = genericObject
a: genericObject.type = [email protected]
虽然object
声明与new
表达式具有不同的语义,但本地object
声明适用于所有意图,目的与具有相同名称的lazy val
相同。考虑:
class Foo(name: String) {
println(name+".new")
def doSomething(arg: Int) {
println(name+".doSomething("+arg+")")
}
}
def bar(x: => Foo) {
x.doSomething(1)
x.doSomething(2)
}
def test1() {
lazy val a = new Foo("a")
bar(a)
}
def test2() {
object b extends Foo("b")
bar(b)
}
test1
限定a
作为懒惰VAL与Foo
新实例初始化,而test2
b
定义为一个object
延伸Foo
。 实质上,它们都会懒惰地创建一个Foo
的新实例并为其命名(a
/b
)。
,您可以尝试在REPL并验证它们都具有相同的行为:由语言
scala> test1()
a.new
a.doSomething(1)
a.doSomething(2)
scala> test2()
b.new
b.doSomething(1)
b.doSomething(2)
所以尽管object
和lazy val
之间的语义差异(尤其是特殊处理的object
的,如Daniel C.所述Sobral), a lazy val
总是可以用相应的object
代替(这不是一种非常好的做法),同样也适用于属于类/特征成员的lazy val
/object
。 我能想到的主要实际区别是对象具有更具体的静态类型:b
类型为b.type
(它扩展了Foo
),而a
恰好类型为Foo
。
lazy val a:Foo =一个 – 2014-07-11 10:52:55
可能重复[val和对象在scala类内?](http://stackoverflow.com/questions/3448691/val-and-object-inside-a-scala-class) – Bergi 2016-05-25 04:00:25