如果我在 Scala 中定义多个重载构造函数,我不能定义默认值吗?

Posted

技术标签:

【中文标题】如果我在 Scala 中定义多个重载构造函数,我不能定义默认值吗?【英文标题】:Can't I define defaults if I define multiple overloaded constructors in Scala? 【发布时间】:2011-04-23 09:50:20 【问题描述】:

我已经定义了多个构造函数,它们都有一些默认参数值。看起来正确(我看不出有任何歧义),但 Scala (2.8) 编译器抱怨:

构造函数的多个重载替代项定义默认参数

这是否意味着我根本无法为重载的构造函数定义默认值?

让我来说明一下情况(当然是原始的,但说明性的):

class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) def this (subject : Int, factor : Int = 1, doItRight : Boolean = true) = this(subject.toDouble , factor, doItRight) def this (subject : String, factor : Int = 1, doItRight : Boolean = true) = this(subject.toDouble , factor, doItRight) def this () = this(defaultSubject)

【问题讨论】:

您介意发布您拥有的代码吗? 【参考方案1】:

直接取自编译器的源代码:

// only one overloaded alternative is allowed to define default arguments

一般来说,我不建议您混合使用重载和默认值。即使没有冲突,它也会使您的代码更难阅读。

更新

由于您添加了代码,现在很明显您不想/不需要覆盖每个辅助构造函数的默认值。在您的特定情况下,我什至可能会质疑是否需要那些额外的构造函数; Int=>Double 已经可以作为隐式转换为您使用,而 String=>Double 看起来您可能会歪曲类型系统:)

另外... 作为重载构造函数的替代方案,您可以仅使用默认值定义主构造函数,然后重载伴随对象的 apply 方法并将其用作工厂。这当然是完全可选的,但通过使用案例类,它正在迅速成为一种模式。

【讨论】:

在这种情况下使用工厂似乎是没有必要的,并且违反了奥卡姆剃刀原则。恕我直言,为所有情况(手动应用默认值)实现构造函数会更漂亮,所以我已经完成了(虽然看起来太老了,而且会自我重复)。 如果我需要这些数量的构造函数,我会仔细检查我的代码。这些天我几乎不需要一个...... 请不要以我对这个答案的支持来表示我同意这种语言限制。【参考方案2】:

重载失败是因为您(不必要地)使用默认值定义了多个构造函数。改为这样做:

class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) 

  def this (subject : Int) = 
    this(subject.toDouble)
  

  def this (subject : String) = 
    this(subject.toDouble)
  

  def this () = 
    this(defaultSubject)
  

【讨论】:

但是如果在这种情况下,如果主题 Int 或 String,则不需要显式指定 factor 和 doItRight 参数? @Ivan,不,您不需要指定它们,因为您已经在主构造函数中为它们设置了默认值。 我猜这是因为您的代码一开始并没有达到预期的效果。使用您的代码,您不能执行“ new A("Subject", 98, false) ”之类的操作 @frank,是的,你可以。主构造函数允许这样做。 @MiaClarke 好吧,也许我做错了,但是在 scala 2.10 上测试了几次之后,我得到了这个: scala> val pa = new A("dsa", 89, false) :8: 错误:类型不匹配;发现 : String("dsa") required: Double val pa = new A("dsa", 89, false) ^

以上是关于如果我在 Scala 中定义多个重载构造函数,我不能定义默认值吗?的主要内容,如果未能解决你的问题,请参考以下文章

Scala学习补充篇

C++类-构造函数的重载

C++类-构造函数的重载

构造函数

Scala - 处理“方法的多个重载替代方案......定义默认参数”

每个构造函数,方法和运算符重载的c ++多重定义错误[重复]