Scala Case Class默认参数疑问:首参带默认值如何实例化
解决Scala Case Class默认参数的使用问题
这是Scala里默认参数使用时很容易踩的小坑,我来给你拆解清楚:
为什么原来的写法会报错?
你最初的定义是:
case class Task(uuid: String = java.util.UUID.randomUUID().toString, n: Int)
这里uuid是第一个参数(带默认值),n是第二个参数(无默认值)。Scala的默认参数规则是:如果没有显式指定参数名,编译器会严格按照参数列表的顺序匹配传入的值。当你写Task(1)时,编译器会把1当成第一个参数uuid的取值,但1是Int类型,和uuid要求的String类型不匹配,自然就触发编译错误了。
为什么调整参数顺序就正常了?
当你把定义改成:
case class Task(n: Int, uuid: String = java.util.UUID.randomUUID().toString)
此时n是第一个无默认值的参数,uuid是第二个带默认值的参数。这时候写Task(1),编译器会自动把1匹配到第一个参数n,第二个参数uuid则使用默认生成的UUID,完全符合规则,所以能正常运行。
不用调整参数顺序的解决办法
如果你不想改变参数的定义顺序,还有更直接的方式:使用命名参数显式指定你要赋值的参数,让编译器跳过带默认值的参数。比如针对最初的定义,你可以这样创建实例:
// 显式指定n的参数名,uuid使用默认值 val myTask = Task(n = 1) // 当然也可以同时指定uuid和n的值 val customUuidTask = Task(uuid = "my-custom-uuid", n = 2)
核心规则总结
Scala默认参数的使用逻辑可以简单记为:
- 带默认值的参数如果在参数列表末尾,可以直接省略,编译器会自动填充默认值
- 带默认值的参数如果不在末尾,必须通过命名参数来明确指定后续参数的赋值,才能使用前面参数的默认值
内容的提问来源于stack exchange,提问作者Alexandr
相关产品推荐
相关产品推荐

