我是 Scala 的新手。
Here是我正在尝试编写的 Models.scala。
当我运行 sbt 包时,它给出了错误
Models.scala:25: models.Session.Network.type does not take parameters
[error] network : Network = Network() ,
我不明白为什么会发生这个错误,我在执行 Network() 时没有传递任何参数。有人可以帮帮我吗
最佳答案
这是一个较小的代码,可以重现您的问题:
case class A(b:B = B(3, 5))
case class B(i: Int, j: Int)
object A {
val B = "whatever"
}
在第一行,我们得到
too many arguments for method apply: (index: Int)Char in class StringOps
发生的情况是,当您定义 case 类的签名时,您同时定义了构造函数的签名(当您使用 new 调用时)和伴随对象中的 apply 方法的签名(当您不使用 new 调用时)。
当您在参数中放置默认值时(代码中的 Network() 和我的中的 B(3, 5)),此代码将在构造函数和伴随对象的 apply 方法的上下文中进行编译。
当你定义了一个伴随对象 Session 时,apply 方法会自动添加到这个对象中。碰巧你的伴生对象中的 Network() 意味着你在那里定义的 Network 对象上的 Network.apply() ,它意味着我的代码中值为“whatever”的字符串 B 。
真正奇怪的是,默认表达式可能具有不同的含义,但在构造函数和 apply 方法的上下文中都是正确的。在这种情况下,您可能会得到不同的行为,具体取决于您是否使用 new 调用。
这是一个例子:
case class A(b:B = bb)
case class B(i: Int, j: Int)
object bb extends B(3, 4)
object A {
val bb = new B(7, 2)
}
object Test extends App {
println(A())
println(new A())
}
运行测试将打印
A(B(7,2))
A(B(3,4))
对于您的具体问题,有一些简单的解决方法。
network: Network = models.Network(),
显然会起作用,因为很明显,您希望 Network 包含在包中,而不是对象 Session 中。
network: Network = new Network(),
也可以工作,因为使用新的,编译器将查找 Network 类型而不是 Network 值。在伴随对象 session 中,网络值被本地声明遮蔽,但网络类型不是。
IMO,前者(models.Network)更清晰。
附注。我检查了规范,我相信这种奇怪的行为是符合规范的。即,(5.3.2) 一个 apply 方法在伴生对象内生成,其参数列表与构造函数相同。这包括默认值,然后将在伴随对象内编译。
关于Scala case class.type 不带参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26767525/