我发现在我的项目中使用它非常方便:
case class Thing(a: Option[String], b: Option[String], c: Option[String])
...
val a = Thing(a = Some("A"))
val b = Thing(b = Some("B"))
val c = Thing(b = Some("B"), c = Some("C"))
它实际上减少了许多丑陋的无定义并且看起来很可读,但是现在我想知道这与它之间的性能/实现观点有什么不同吗?:
val a = Thing(Some("A"), None, None)
val b = Thing(None, Some("B"), None)
val c = Thing(None, Some("B"), Some("C"))
由于
答案 0 :(得分:1)
从语义上讲,没有区别,因为None
是一个单例对象。但是,从性能方面来说,我们可以看到在底层生成了什么类型的代码。
case class Thing(
a: Option[String] = None,
b: Option[String] = None,
c: Option[String] = None
)
object Thing {
def foo() = {
val a1 = Thing(a = Some("A"))
val b1 = Thing(b = Some("B"))
val c1 = Thing(b = Some("B"), c = Some("C"))
val a2 = Thing(Some("A"), None, None)
val b2 = Thing(None, Some("B"), None)
val c2 = Thing(None, Some("B"), Some("C"))
}
}
我相信这是你要问的那种事情的一个例子。我们可以使用scalac Thing.java -Xprint:jvm
编译它,以查看Scala编译器在删除所有语法糖之后剩下的内容。
val a1: Thing = new Thing(new Some("A"), Thing.apply$default$2(), Thing.apply$default$3());
val b1: Thing = {
<artifact> val x$1: Some = new Some("B");
<artifact> val x$2: Option = Thing.apply$default$1();
<artifact> val x$3: Option = Thing.apply$default$3();
new Thing(x$2, x$1, x$3)
};
val c1: Thing = {
<artifact> val x$4: Some = new Some("B");
<artifact> val x$5: Some = new Some("C");
<artifact> val x$6: Option = Thing.apply$default$1();
new Thing(x$6, x$4, x$5)
};
val a2: Thing = new Thing(new Some("A"), scala.None, scala.None);
val b2: Thing = new Thing(scala.None, new Some("B"), scala.None);
val c2: Thing = new Thing(scala.None, new Some("B"), new Some("C"));
因此使用命名语法可以引入一些中间变量。但函数调用本质上是模数堆栈空间的几个字节。更有可能的是,JIT会将这些编译成类似的代码片段,所以我说你几乎不用担心。