- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑这个简单的例子:
trait A { def a: String = "a"; def a2: String }
case class C(b: String, c: String) extends A {
val a2 = "a2"
}
val c = C("b", "")
val copy = c.copy(c="c")
当我用 .copy(c="c")
更新字段 c
时,其他字段(a
,a2
和 b
) 复制了吗?尽管只复制了它们的引用,但如果我有一个巨大的层次结构树,.copy
会变得非常昂贵吗?
类似地:
class Foo {
val list = List(1,2,3,4,5,6)
}
val foo1 = new Foo
val foo2 = new Foo
foo1
和 foo2
共享一个 List
实例,或者每次我实例化一个 Foo
它都会创建一个新的 List
?如果 list
是 var
而不是 val
会怎么样?
最佳答案
通常 Scala 是不可变的,您通常必须自己处理可变情况。此外,案例类本质上是不可变的,它们的复制方法由编译器生成。所以是的,他们将共享相同的对象引用。这是不可变性很好的原因之一。
你的第二个问题有点不同。在那种情况下,类是在单独的上下文中一个接一个地构造的。
检查正在编译的内容也是一个好主意:
>scalac -print test.scala
[[syntax trees at end of cleanup]] // test.scala
package test {
class Foo extends Object {
private[this] val list: List = _;
<stable> <accessor> def list(): List = Foo.this.list;
def <init>(): b.Foo = {
Foo.super.<init>();
Foo.this.list = immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1, 2, 3, 4, 5, 6}));
()
}
}
}
由此可见,Scala 每次都会创建一个新的列表。将其更改为 var
不会改变任何内容,我们可以检查:
>scalac -print test.scala
[[syntax trees at end of cleanup]] // test.scala
package test {
class Foo extends Object {
private[this] var list: List = _;
<accessor> def list(): List = Foo.this.list;
<accessor> def list_=(x$1: List): Unit = Foo.this.list = x$1;
def <init>(): b.Foo = {
Foo.super.<init>();
Foo.this.list = immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1, 2, 3, 4, 5, 6}));
()
}
}
}
它只为它生成了一个 setter 方法 (def list_=(x$1: List)
)。
如果您想在两种情况下都引用相同的列表,则使用对象的默认列表对其进行初始化:
object Foo {
val DefaultList = List(1,2,3,4,5,6)
}
class Foo {
var list = Foo.DefaultList
}
编译为以下内容:
>scalac -print test.scala
[[syntax trees at end of cleanup]] // test.scala
package test {
object Foo extends Object {
private[this] val DefaultList: List = _;
<stable> <accessor> def DefaultList(): List = Foo.this.DefaultList;
def <init>(): test.Foo.type = {
Foo.super.<init>();
Foo.this.DefaultList = immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1, 2, 3, 4, 5, 6}));
()
}
};
class Foo extends Object {
private[this] var list: List = _;
<accessor> def list(): List = Foo.this.list;
<accessor> def list_=(x$1: List): Unit = Foo.this.list = x$1;
def <init>(): test.Foo = {
Foo.super.<init>();
Foo.this.list = Foo.DefaultList();
()
}
}
}
如您所见,列表只创建一次,然后通过 def DefaultList(): List
分配给每个 Foo 类实例化的引用。
关于scala - 创建(或复制)一个对象有多昂贵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20644898/
我正在阅读 MongoDB,并试图了解它的最佳用途。我没有看到明确答案的一个问题是哪些操作便宜或昂贵,以及在什么条件下。 你能帮忙澄清一下吗? 谢谢。 最佳答案 人们经常声称 mongodb 的写入速
我正在寻找一个主要来源(或一个非常好的解释)来支持在为 iPhone 编写软件时使用 autorelease 是危险的或过于昂贵的说法。 许多开发者都提出了这种说法,我什至听说 Apple 不推荐它,
我意识到这离微优化领域太远了,但我很想知道为什么调用 DateTime.Now 和 DateTime.UtcNow 如此“昂贵”。我有一个示例程序,它运行几个场景来做一些“工作”(添加到一个计数器)并
我是一名优秀的程序员,十分优秀!