Scala:在案例类构造函数中设置默认值无效

3

我正在创建一个带有默认值构造函数的case class:

abstract class Interaction extends Action
case class Visit(val url: String)(val timer: Boolean = false) extends Interaction

但是如果我不使用它的所有参数,就无法创建任何一个实例,例如,如果我写:

Visit("https://www.linkedin.com/")

编译器会报错:
missing arguments for method apply in object Visit;
follow this method with `_' if you want to treat it as a partially applied function
[ERROR]     Visit("http://www.google.com")

我需要做什么来解决这个问题?

你定义它时使用柯里化(例如这里),是否有原因?如果没有,如下所建议的,你可以在第一组中定义所有参数,你的默认值将按要求工作。如果你需要柯里化/第二组参数,则额外的括号将导致该组参数的默认值被应用。 - wwkudu
2个回答

15

您需要告诉编译器这不是部分应用的函数,而是您想要第二组参数的默认值。只需打开并关闭括号即可。

scala> Visit("https://www.linkedin.com/")()
res1: Visit = Visit(https://www.linkedin.com/)

scala> res1.timer
res2: Boolean = false

编辑,以解释@tribbloid的评论。

如果使用下划线(_)代替创建访问,则创建部分应用的函数,然后可以使用该函数创建Visit对象:

val a = Visit("asdsa")_ // a is a function that receives a boolean and creates and Visit
a: Boolean => Visit = <function1> 

scala> val b = a(true) // this is equivalent to val b = Visit("asdsa")(true)
b: Visit = Visit(asdsa)

非常感谢!我曾经猜测,部分应用的函数在存在歧义时应该总是有一个下划线。看起来我错了,这是唯一的选项。 - tribbloid
Scala的一个有趣特性是,当旧特性和新特性发生歧义时,旧特性总是胜出,而新特性则被舍弃。由括号声明的元组上的中缀方法作为运算符永远不起作用,因为编译器认为这些括号是优先级括号 :) - tribbloid
@tribbloid,看到我的编辑了吗?我希望它能澄清你的疑惑。 - Vinicius Miana
我之前在其他地方看到过这个规则,所以我很困惑,因为如果这是定义 PAF 的唯一方法,那么 Visit("Something") 就不会有歧义。Scala 有一些奇怪的规则来判断你是否需要使用下划线。 - tribbloid
还有一个问题:我可以通过在第二个参数上使用隐式分隔符来解决这个问题,但这会有什么副作用吗? - tribbloid
这实际上是一个有趣的想法。具有默认值的隐式参数可能有效(以删除额外的括号)。我能想到的唯一副作用是,如果在某个调用上下文中具有相同类型的隐式值,则默认值将被覆盖(有些人可能认为这是一种功能而不是错误,允许在上下文中覆盖默认值)。 - Andrzej Wąsowski

5
请按照以下方式更正指定案例类中可选字段的语法:
case class Visit(val url: String,val timer: Boolean = false) extends Interaction

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