具有非默认构造函数参数的Scala类单例

时间:2017-10-03 15:02:59

标签: scala constructor companion-object callbyname

我已经阅读过从伴侣类继承的对象的问题。

例如:

但我有一个不同的问题(我不确定这是一个错误)

我有以下代码:

class Scala(name: String)

import Scala._

object Scala extends Scala(TEST_NAME){
  val TEST_NAME = "test name"
}

请注意,我使用的是在随播对象范围内定义的变量,然后将其传递给super的构造函数。

我收到以下编译错误:

Scala.scala:5: error: super constructor cannot be passed a self reference 
unless parameter is declared by-name

object Scala extends Scala(TEST_NAME){
                           ^
one error found

我尝试过的其他变体:

按姓名呼叫:

class Scala(name: => String)

import Scala._

object Scala extends Scala(TEST_NAME){
  val TEST_NAME = "test name"
}

命名参数:

class Scala(name: String)

import Scala._

object Scala extends Scala(name = TEST_NAME){
  val TEST_NAME = "test name"
}

他们两人:

class Scala(name: => String)

import Scala._

object Scala extends Scala(name = TEST_NAME){
  val TEST_NAME = "test name"
}

一些环境细节:

  • java:java version "1.8.0_144"
  • javac:javac 1.8.0_144
  • scala:Scala code runner version 2.12.3
  • scalac:Scala compiler version 2.12.3
  • 操作系统:Darwin ***.local 17.0.0 Darwin Kernel Version 17.0.0: Thu Aug 24 21:48:19 PDT 2017; root:xnu-4570.1.46~2/RELEASE_X86_64 x86_64

更新

对于有兴趣解决此事的任何人:

3 个答案:

答案 0 :(得分:2)

对于您的受限用例:

scala> class C(s: String) ; object X extends C(X.x) { final val x = "hello, world" }
defined class C
defined object X

内联常量值定义(根据规范)。

答案 1 :(得分:1)

您可以使用Scala 3中将要删除的模糊功能:早期初始化程序。它允许您在调用超类构造函数之前指定要运行的init代码。

class Scala(name: String)

object Scala extends {
  val TEST_NAME: String = "test name"
} with Scala(TEST_NAME) { /* rest of object code */ }

请注意,不需要导入 - TEST_NAME已在范围内。

这里有Scastie snippet来证明它有效。

答案 2 :(得分:0)

如果上面的代码编译完毕,那么你可以编写

class A(val x: String)

object B extends A(B.x_again) {

  val x_again = x
}

当然看起来不太好。