Scala编译器如何在trait中定义final val?
我经常使用无私特质模式,我需要在特质中使用“昂贵”常量: 我希望在我的所有应用程序中都有这些值的一个实例,这可能需要计算几个步骤 然而,无私的特质模式导致以下设计:Scala编译器如何在trait中定义final val?,scala,scalac,scala-compiler,Scala,Scalac,Scala Compiler,我经常使用无私特质模式,我需要在特质中使用“昂贵”常量: 我希望在我的所有应用程序中都有这些值的一个实例,这可能需要计算几个步骤 然而,无私的特质模式导致以下设计: 我的羽毛 对象MyStuff扩展了MyStuff 显然,将常量放入对象中并在特征中使用它们会创建循环依赖关系。然而,将它们放在trait上,使得所有扩展trait的类都可以覆盖它们,因此它们肯定不是应用程序范围的单例 Scala编译器是否“足够聪明”使trait中的final VAL变为“旧java公共静态final” 类似于公
- 我的羽毛
- 对象MyStuff扩展了MyStuff
Scala编译器是否“足够聪明”使trait中的final VAL变为“旧java公共静态final” 类似于
公共静态最终版
,您应该使用这样的伴生对象:
trait MyStuff
object MyStuff {
val publicStaticFinal = ...
}
在本例中,scalac
使用方法public int publicStaticFinal()
创建一个单例对象(publicStaticFinal MyStuff$MODULE$
)。如果愿意,可以将此方法设置为final
对于public final
-使用final val
:
trait MyStuff
final val publicFinal = ...
}
在这种情况下,
scalac
创建了一个带有public abstract int publicFinal()
的接口,并在MyStuff
的每个祖先中实现它,因为public final int publicFinal()不,scala不会将trait中的final val
转换为java静态final
,,因为final val
必须是继承类的实例成员(而不是静态成员)
scala> trait myStuff { final val Test="test" }
defined trait myStuff
scala> class t extends myStuff
defined class t
scala> t.Test
<console>:8: error: not found: value t
t.Test
^
// we need an instance of t to access Test
scala> new t
res2: t = t@35612600
scala> res2.Test
res3: String = test
你关心的循环依赖性的一个例子是什么
通常,这可以通过在trait或lazy vals中适当使用def来解决
下面是由默认参数(在伴随对象中合成)诱导的
但如果你需要渴望,你可以提前定义:
但是,如果计算w
使用Foo
的成员,则您必须变得懒惰:
trait Foo {
val v = 2 * Foo.w
def x = 7
}
object Foo extends Foo {
lazy val w = 3 * x
}
这是我今天第二次需要一个问题的常见问题,但我还没有找到它的新家
(编辑:为什么,)访问Test
而不使用t
实例:val-mine:myStuff=null;mine.Test
。
scala> :pa
// Entering paste mode (ctrl-D to finish)
trait Foo {
val v = 2 * Foo.w
}
object Foo extends {
private val w = 3
} with Foo
// Exiting paste mode, now interpreting.
defined trait Foo
defined object Foo
scala> Foo.v
res11: Int = 6
trait Foo {
val v = 2 * Foo.w
def x = 7
}
object Foo extends Foo {
lazy val w = 3 * x
}