2

由于 Scala 2.13 早期的初始化程序已被弃用。

如何创建一个值以传递给应该计算(基于其他构造函数参数)并且完全私有的超类,所以在类初始化时它不能被传递?

直到今天我所做的一个例子是:

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)

(这只是一个带有假类名的示例,因为我不能分享我的源代码)

如果我定义了一个特征,我不知道如何将值传递给超类而不暴露它并在类构造函数中覆盖它。

我看到 Dotty (Scala 3) 允许特征参数,但 Scala 2.13 不允许。

如果您知道解决方案,请提供一个带有解释的片段!谢谢!

4

2 回答 2

2

首先,如果您可以控制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类,你也可以简单地传递一个方法来定义cfromab以这种方式:

class ActiveMQService(val a: ConfigElement, val b: ConfigElement, f: (ConfigElement, ConfigElement) => Config) 
  extends JmsServiceInitialiser(f(a,b))

这两种解决方案都有点难看,我建议您认真考虑您是否真的需要ab以及c=a+b 作为班级成员。

于 2019-10-03T13:30:01.137 回答
0

我发现这是通过在将变量传递给超类时简单地计算变量来实现的:

abstract class JmsServiceInitialiser(val qConfig: Config)

class ActiveMQService(
  val configA: ConfigElement,
  val configB: ConfigElement
) extends JmsServiceInitialiser({
  println(configA)
  println(configB)
  ...
  configA + configB
})

如果您有更好的解决方案,请发布您的答案。

于 2019-10-03T13:25:07.187 回答