Scala额外的无参构造函数加默认构造函数参数

9
我正在使用Scala 2.8默认参数构造函数,由于Java兼容性的原因,我想要一个使用默认参数的无参构造函数。
出于非常明智的原因,这不起作用:
class MyClass(field1: String = "foo", field2: String = "bar") {
    def this() = {
        this() // <-- Does not compile, but how do I not duplicate the defaults?
    }
}

我在想我是否遗漏了什么。有没有不需要复制参数默认值的想法?

谢谢!


1
有一个票据在 https://lampsvn.epfl.ch/trac/scala/ticket/4278 - Seth Tisue
2
我曾在我第一次亲身参加的Scala会议上支持那个提案,但我的发言却被贪婪的“不要用你的特殊情况破坏这门语言”的人吞噬了。现在每个使用案例都只能靠自己了! - psp
5个回答

12

我不太建议这样做,但是您可以通过向构造函数添加另一个参数来实现:

class MyClass(a: String = "foo", b: String = "bar", u: Unit = ()) {
  def this() { this(u = ()) }
}

Unit是一个很好的选择,因为你只能传递一个东西到里面,所以明确地传递默认值不允许出现任何错误的可能性,同时它还可以让你调用正确的构造函数。

如果你愿意复制其中的一个默认值,你可以使用相同的策略,只需覆盖选择的那个默认值,而不是添加单元参数。


我同意这符合我的问题的精神(最小化重复),但这不是一个好的做法。感谢您的回答! - jkl

4
作为一个好奇心强的技术人员,我有一个非常“hack”的解决方案:你可以使用默认参数的内部表示。
class MyClass(field1: String = "foo", field2: String = "bar") { 
  def this() =  this(MyClass.init$default$1)
}

注意需要在 this(MyClass.init$default$1) 中包含 MyClass。部分解释是默认参数保存在伴生对象中。

4
您可以考虑使用工厂方法:
class MyClass(field1: String = "foo", field2: String = "bar")
object MyClass {
    def newDefaultInstance = new MyClass
}

你可以从Java中调用MyClass.newDefaultInstance()

另一种可能性是移动你指定默认值的位置:

class MyClass(field1: String, field2: String) {
  def this() = this(field1="foo", field2="bar")
}

如果您正在使用Spring等框架,并且需要使用反射来查找0-arg构造函数,那么这种风格特别有用。


谢谢您的建议。在我的情况下,第一种方法行不通,因为我正在初始化一个Servlet(所以我需要无参构造函数)。第二种方法是可行的,但是在测试中,我会失去默认值提供的愉悦的默认行为。如果我不需要无参构造函数,我可能会选择第一种方法。 - jkl

0

并非适用于所有目的,但是通过使用子类可能会解决问题:

class DefaultMyClass extends MyClass()

0
如果我的理解没有错的话,以下代码对我来说非常有效。
class Employee (

   ){
  def this( name :String ,

    eid :Int ){
    this();
  }
}

`


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