在Scala中,伴生对象没有与case类关联

4

我有些困惑为什么这段代码不能运行。我是在二叉树部分从99个Scala问题(http://aperiodic.net/phil/scala/s-99/)中得到的。在我看来,它是有效的:Node对象是Node类的伴生对象,并为树上的叶子节点添加了一个构造函数。但是当我尝试编译它时,我得到以下错误:

<console>:10: error: too many arguments for method apply: (value: T)Node[T] in object Node

    def apply[T](value: T): Node[T] = Node(value, End, End)

如果我去掉两端,就不会有任何编译错误,但如果我用一个单值来创建一个节点,我会陷入无限循环。因此看起来 apply 正在构造更多的节点对象,并且没有与节点类关联起来。任何帮助都将不胜感激。
sealed abstract class Tree[+T]
case class Node[+T](value: T, left: Tree[T], right: Tree[T]) extends Tree[T] {
    override def toString = "T(" + value.toString + " " + left.toString + " " + right.toString + ")"
}
case object End extends Tree[Nothing] {
    override def toString = "."
}
object Node {
    def apply[T](value: T): Node[T] = Node(value, End, End)
}

scalac可以从源文件中编译它。我相信这只是一个控制台问题。 - CheatEx
1个回答

12
在我的电脑上可以运行(见下文)。你是否在同一个文件中定义了它们?

Welcome to Scala version 2.9.0.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_24).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

sealed abstract class Tree[+T]
case class Node[+T](value: T, left: Tree[T], right: Tree[T]) extends Tree[T] {
    override def toString = "T(" + value.toString + " " + left.toString + " " + right.toString + ")"
}
case object End extends Tree[Nothing] {
    override def toString = "."
}
object Node {
    def apply[T](value: T): Node[T] = Node(value, End, End)
}

// Exiting paste mode, now interpreting.

defined class Tree
defined class Node
defined module End
defined module Node

scala> Node("123")
res0: Node[java.lang.String] = T(123 . .)

scala>

编辑 从您的评论中可以看出,repl中的:load命令逐行解释文件中的每一行,您可以在这里找到该代码的实现。但是,在REPL中使用此方法不起作用,因为(我认为)每个被解释的行都会在其自己的包中进行编译。有关更多详细信息,请参见此帖子。也许这可以成为REPL的未来增强功能。但原则上,您的代码没有问题:使用:paste模式或只编译scalac均可正常工作。


scala> case class A(i: Int, i2: Int)
defined class A

scala> object A {
     | def apply(i: Int): A = A(i, i)
     | }
:25: error: too many arguments for method apply: (i: Int)A in object A
       def apply(i: Int): A = A(i, i)

scala> object A {
         def apply(i: Int): A = new A(i, i)
       }
defined module A
warning: previously defined class A is not a companion to object A.
Companions must be defined together; you may wish to use :paste mode for this.

注意:我在JIRA上找不到任何增强请求,所以我创建了这个问题


1
它在粘贴模式下可以工作,但在Scala控制台中运行“:load ./tree.scala”时无法工作。不确定区别在哪里。 - Kaleidoscope

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接