4

我对 Scala 完全陌生。现在我正在尝试将我在标准 ML 中编写的解析器移植到 Scala 并遇到以下代码问题:

abstract class Token
case class Zero extends Token
case class At extends Token
//...

object Tokenizer {
  def tokenize(seq : List[Char]) : List[Token] = seq match {
    case List() => error("Empty input")
    case '0' :: rest => Zero :: tokenize(rest)
    case '@' :: rest => At :: tokenize(rest)
    //...
  }  
}

在 SML 中,我不必声明 tokenize() 方法的返回类型,但似乎 Scala 需要它,并且它对我提供的类型不满意(它抱怨零,At 是无效类型,它们应该是代币类型)。请注意,我还想在解析阶段的稍后时间点匹配令牌列表。

我在网上和 stackoverflow 本身上进行了一些搜索,以查看之前是否曾提出过类似的问题(看起来如此微不足道),但不知何故我找不到任何东西。我很确定我有一些基本错误,请随时启发我:)

4

2 回答 2

9

At并且Zero是类,而不是对象,因此它们本身不是Token. case class您可以通过从更改为来修复您的代码case object

case object Zero extends Token
case object At extends Token

您需要指定函数的返回类型的原因是 Scala 的编译器无法确定递归函数的类型,您可以在此处阅读更多相关信息:为什么 Scala 需要递归函数的返回类型?

于 2011-08-15T19:49:51.880 回答
8

如果你想创建新的实例ZeroAt案例类,那么你应该使用apply工厂方法来实例化它们(或new关键字:)new Zero,就像这样(在 ScalaZero()中等于Zero.apply()):

case '0' :: rest => Zero() :: tokenize(rest)

如果你只写Zero(而不是Zero()),那么你正在使用Zero类的伴随对象,它是由编译器自动创建的。

于 2011-08-15T19:53:02.847 回答