用许多实现扩展一个类,每个实现在Scala中都有主方法
假设我有一个带有单个抽象方法的标记器类用许多实现扩展一个类,每个实现在Scala中都有主方法,scala,Scala,假设我有一个带有单个抽象方法的标记器类 trait Tokenizer { def tokenize(sentence: String): List[String] } 我将实现许多提供实现的标记器。我希望这些标记器中的每一个都有一个main方法。我的第一个想法是编写如下代码: abstract class TokenizerMain(tokenizer: Tokenizer) { def main(args: Array[String]) = println(tokenize
trait Tokenizer {
def tokenize(sentence: String): List[String]
}
我将实现许多提供实现的标记器。我希望这些标记器中的每一个都有一个main方法。我的第一个想法是编写如下代码:
abstract class TokenizerMain(tokenizer: Tokenizer) {
def main(args: Array[String]) = println(tokenizer.tokenize(args(0)).mkString(" "))
}
class TokenizerOne(val model: String = "foo") extends Tokenizer {
def tokenize(sentence: String) = List("asdf")
}
object TokenizerOne extends TokenizerMain(new TokenizerOne) {
}
然而,我得到了错误“超级构造函数不能传递自引用,除非参数是按名称声明的”。我可以将objecttokenizerone
重命名为objecttokenizeronemain
,但我希望它与类
保持相同。有更好的方法吗
更新:此问题似乎是由TokenizerOne的隐式构造函数参数
model
引起的。下面是一个简化的代码示例,给出了相同的错误
class Foo(t: Any)
class Bar(x: String = "bar")
object Bar extends Foo(new Bar())
// ^
// Error, super constructor cannot be passed a self reference unless
// parameter is declared by-name
字节码有助于解释发生了什么。从REPL,
scala> class Foo(t: Any)
scala> class Bar(x: String = "bar")
scala> :javap -v Bar
Compiled from "<console>"
public class Bar extends java.lang.Object implements scala.ScalaObject
...
{
public Bar(java.lang.String);
...
啊,这是在伴生对象中定义的,它属于类Bar$
(只有Scala编译器应该知道这一点)
因此,在extends Foo(new Bar())
中,在Bar
的超类初始化期间(在对象Bar
实际构造之前),您试图访问对象Bar
中的方法
如果这不是Scala编译器中的错误,那么它就是一条令人困惑的错误消息!我不能说是哪个。我在bug追踪器中提交了这个问题
作为一种解决方法,您可以避免使用默认值:
对象栏扩展Foo(新栏(“Bar”))
我使用的是2.9.1。我忘记了类TokenizerOne上的一个隐式构造函数参数——很抱歉。添加此构造函数参数后,问题就出现了。
scala> :javap -v Bar$
...
public java.lang.String init$default$1();
Code:
Stack=1, Locals=1, Args_size=1
0: ldc #16; //String bar
2: areturn
LineNumberTable:
line 7: 0