Scala case class.type 不带参数

标签 scala

我是 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/

相关文章:

scala - 定义供 java 使用的 scala function1 类型错误

scala - Akka Http 性能调优

Scala Try[Unit] 混淆

硬币找零算法失败

scala - 为什么 getOrElse 会丢失 scalaz 中的类型推断

scala - Controller 中的授权检查 - Scala/Play

mysql - 如何使用Slick 3.0调用MySQL中的存储过程和定义函数

scala - 如何将 Scala @specialized 用于围绕基元的内存高效包装类?

java - 'java.lang.AssertionError : assertion failed' Error while starting Scala-IDE(Eclipse)

scala - 简化方法: Merge two Options to one result