如何在 Scala 中没有早期初始化器的情况下为超类构造函数创建参数
How to create param for superclass constructor without early initialiser in Scala
由于 Scala 2.13 早期的初始化器已被弃用。
我如何创建一个值传递给 superclass 应该计算(基于其他构造函数参数)并且完全私有,所以在 class 初始化时它不能被传递?
直到今天我所做的一个例子是:
abstract class JmsServiceInitialiser(val qConfig: Config)
class ActiveMQService(
val configA: ConfigElement,
val configB: ConfigElement
) extends {
val config: Config = {
println(configA)
println(configB)
...
configA + configB
}
} with JmsServiceInitialiser(config)
(这只是一个带有假 classes 名称的示例,因为我无法共享我的源代码)
如果我定义了一个特征,我不知道如何将值传递给 superclass 而不公开它并在 class 构造函数中覆盖它。
我看到 Dotty (Scala 3) 允许 trait 参数,但 Scala 2.13 不允许。
如果您知道解决方案,请提供一个带有解释的片段!谢谢!
我发现这是通过在将变量传递给超类时简单地计算变量来实现的:
abstract class JmsServiceInitialiser(val qConfig: Config)
class ActiveMQService(
val configA: ConfigElement,
val configB: ConfigElement
) extends JmsServiceInitialiser({
println(configA)
println(configB)
...
configA + configB
})
如果您有更好的解决方案,请post您的回答。
首先,如果您可以控制 JmsServiceInitialiser
,我会研究将 qConfig
变成 def
的可能性,从而完全避免这个问题。
如果你绝对想保持定义的原样,并且仍然保持相对干净,你可以简单地为运行你的早期初始化器创建一个包装器。
class Config
class ConfigElement {
def +(e: ConfigElement): Config = ???
}
abstract class JmsServiceInitialiser(val config: Config)
class Early(val a: ConfigElement, val b: ConfigElement) {
val c: Config = a + b
}
class ActiveMQService(early: Early) extends JmsServiceInitialiser(early.c) {
val a = early.a
val b = early.b
}
如果你不想声明一个Early
class,你也可以简单地通过一种方法从a
和[=18=定义c
] 这样:
class ActiveMQService(val a: ConfigElement, val b: ConfigElement, f: (ConfigElement, ConfigElement) => Config)
extends JmsServiceInitialiser(f(a,b))
这两种解决方案都有点丑陋,我建议您认真考虑一下您是否真的需要 a
、b
和 c=a+b
作为 class 成员。
由于 Scala 2.13 早期的初始化器已被弃用。
我如何创建一个值传递给 superclass 应该计算(基于其他构造函数参数)并且完全私有,所以在 class 初始化时它不能被传递?
直到今天我所做的一个例子是:
abstract class JmsServiceInitialiser(val qConfig: Config)
class ActiveMQService(
val configA: ConfigElement,
val configB: ConfigElement
) extends {
val config: Config = {
println(configA)
println(configB)
...
configA + configB
}
} with JmsServiceInitialiser(config)
(这只是一个带有假 classes 名称的示例,因为我无法共享我的源代码)
如果我定义了一个特征,我不知道如何将值传递给 superclass 而不公开它并在 class 构造函数中覆盖它。
我看到 Dotty (Scala 3) 允许 trait 参数,但 Scala 2.13 不允许。
如果您知道解决方案,请提供一个带有解释的片段!谢谢!
我发现这是通过在将变量传递给超类时简单地计算变量来实现的:
abstract class JmsServiceInitialiser(val qConfig: Config)
class ActiveMQService(
val configA: ConfigElement,
val configB: ConfigElement
) extends JmsServiceInitialiser({
println(configA)
println(configB)
...
configA + configB
})
如果您有更好的解决方案,请post您的回答。
首先,如果您可以控制 JmsServiceInitialiser
,我会研究将 qConfig
变成 def
的可能性,从而完全避免这个问题。
如果你绝对想保持定义的原样,并且仍然保持相对干净,你可以简单地为运行你的早期初始化器创建一个包装器。
class Config
class ConfigElement {
def +(e: ConfigElement): Config = ???
}
abstract class JmsServiceInitialiser(val config: Config)
class Early(val a: ConfigElement, val b: ConfigElement) {
val c: Config = a + b
}
class ActiveMQService(early: Early) extends JmsServiceInitialiser(early.c) {
val a = early.a
val b = early.b
}
如果你不想声明一个Early
class,你也可以简单地通过一种方法从a
和[=18=定义c
] 这样:
class ActiveMQService(val a: ConfigElement, val b: ConfigElement, f: (ConfigElement, ConfigElement) => Config)
extends JmsServiceInitialiser(f(a,b))
这两种解决方案都有点丑陋,我建议您认真考虑一下您是否真的需要 a
、b
和 c=a+b
作为 class 成员。