用许多实现扩展一个类,每个实现在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