Scala 案例类和列表

发布于 2024-11-29 13:43:34 字数 650 浏览 2 评论 0原文

我对 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 需要它并且它对我提供的类型不满意(它抱怨 Zero、At 是无效类型,它们应该是 Token 类型)。请注意,我还想在解析阶段的稍后时间点对标记列表进行模式匹配。

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

I'm completely new to Scala. Right now I'm attempting port a parser I wrote in Standard ML to Scala and having an issue with the following code:

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)
    //...
  }  
}

In SML I wouldn't have to declare the return type of the tokenize() method but it seems Scala needs it and it is somehow not happy with the type I have provided (it complains Zero, At are invalid types and that they should be of type Token instead). Note that I also want to patten match the token list at a later point in time during the parsing phase.

I did some searching on the web and on stackoverflow itself to see if a similar question has been raised before (it looked so trivial) but somehow I couldn't find anything. I'm pretty sure I've got something basic wrong, please feel free to enlighten me :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很酷又爱笑 2024-12-06 13:43:34

AtZero 是类,而不是对象,因此它们本身不是 Token 的实例。您可以通过从 case class 更改为 case object 来修复代码:

case object Zero extends Token
case object At extends Token

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

At and Zero are classes, not objects, so they are not themselves instances of Token. You can fix your code by changing from case class to case object:

case object Zero extends Token
case object At extends Token

The reason why you need to specify the return type of the function is that Scala's compiler can't figure out the type of recursive functions, you can read more about that here: Why does Scala require a return type for recursive functions?

风吹雪碎 2024-12-06 13:43:34

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

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

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

If you want to create new instances of Zero and At case classes, then you should use apply factory method to instantiate them (or new keyword: new Zero), like this (in Scala Zero() would be equal to Zero.apply()):

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

If you write just Zero (and not Zero()) then you are using companion object of Zero class, that was created automatically by compiler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文