我对Scala完全不熟悉。现在我正在尝试将我在Standard 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需要它,并且它对我提供的类型不满意(它抱怨Zero,At是无效类型和那个它们应该是Token类型)。请注意,我还想在解析阶段稍后的时间点匹配令牌列表。
我在网上和stackoverflow上做了一些搜索,看看之前是否提出了类似的问题(看起来很简单),但不知怎的,我找不到任何东西。我很确定我有一些基本的错误,请随时赐教我:)
答案 0 :(得分:9)
At
和Zero
是类,而不是对象,因此它们本身不是Token
的实例。您可以通过从case class
更改为case object
:
case object Zero extends Token
case object At extends Token
您需要指定函数的返回类型的原因是Scala的编译器无法确定递归函数的类型,您可以在此处阅读更多相关信息:Why does Scala require a return type for recursive functions?
答案 1 :(得分:8)
如果要创建Zero
和At
个案例类的新实例,则应使用apply
工厂方法对其进行实例化(或new
关键字:{{ 1}}),像这样(在Scala new Zero
中等于Zero()
):
Zero.apply()
如果只编写case '0' :: rest => Zero() :: tokenize(rest)
(而不是Zero
),那么您正在使用Zero()
类的伴随对象,它是由编译器自动创建的。