如何在 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))

这两种解决方案都有点丑陋,我建议您认真考虑一下您是否真的需要 abc=a+b 作为 class 成员。