gpt4 book ai didi

scala - 使用许多实现扩展一个类,每个实现在 Scala 中都有主要方法

转载 作者:行者123 更新时间:2023-12-02 07:45:21 24 4
gpt4 key购买 nike

假设我有一个带有单个抽象方法的 Tokenizer 类。

trait Tokenizer {
def tokenize(sentence: String): List[String]
}

我将实现一些提供实现的分词器。我希望每个 Tokenizer 都有一个主要方法。我的第一个想法是编写如下代码:

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) {
}

但是,我收到错误消息“除非按名称声明参数,否则无法向 super 构造函数传递自引用”。我可以将 object TokenizerOne 重命名为 object TokenizerOneMain,但我希望它与 class 保持一致。有更好的方法吗?

更新:这个问题似乎是由 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 类只有一个构造函数,它接受一个 String 参数。但是我们知道 Bar 也有一个使用默认值 x = "bar" 的构造函数,那是从哪里来的呢?

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

啊,这是在属于 Bar$ 类的伴随对象中定义的(只有 Scala 编译器应该知道这一点)。

所以似乎正在发生的事情是,在 extends Foo(new Bar()) 中,您试图在 Bar 初始化期间访问对象 Bar 中的方法 Bar 的父类(super class)(在实际构造对象 Bar 之前)。

如果这不是 Scala 编译器中的错误,那么它就是一个令人困惑的错误消息!我不能说是哪个。我提交了问题SI-5000在错误跟踪器中。

作为解决方法,您可以避免使用默认值:object Bar extends Foo(new Bar("bar"))

关于scala - 使用许多实现扩展一个类,每个实现在 Scala 中都有主要方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7448931/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com