【问题标题】:How can I specify multiple constructors in the case class?如何在案例类中指定多个构造函数?
【发布时间】:2015-11-01 15:42:13
【问题描述】:

我正在尝试创建一个具有多个构造函数的案例类:

object App {
  def main(args: Array[String]) {
    val a = Something("abc", 100500, _ % 2 == 0)
    val b = Something(true, 10, 20)   
    println(s"$a - $b")
  }
}

case class Something(s: String, n: Int, p: Int => Boolean) {
  /*
  Additional constructor -- Wrong way! -- it is imposible to invoke it outside the class
  def this(b: Boolean, x: Int, y: Int) {
    this("", 0, (i: Int) => i % x + y == 0)
  }
  */
}

到目前为止,我的代码不起作用:

Error:(10, 23) type mismatch;
 found   : Boolean(true)
 required: String
    val b = Something(true, 10, 20)
                      ^

要修复它,我需要创建一个伴随对象来保存一个应用函数,该函数代表Something 类的新构造函数:

object Something {    
  def apply(b: Boolean, x: Int, y: Int) = {
    new Something(if (b) "" else "default", 0, _ => {
      (x + y) % 2 == 0
    })
  }   
}

不方便。也许还有其他方法可以将多个构造函数放入案例类?

【问题讨论】:

  • 我认为伴随对象是唯一的方法,因为案例类是代数类型,它不应该有不同的形式(不同的构造函数)。如果你可以为它创建辅助构造函数——我认为它不能很好地与所有案例类功能一起使用——比如模式匹配
  • 您提到了代数类型。于是我查了一下wiki是什么意思,发现是这样的:Each variant has its own constructor, which takes a specified number of arguments with specified types.所以代数类型允许多个构造函数。
  • 我认为不相交的意思是:abstract class Base; case class A(i: Int) extends Base; case class B(s: String) extends Base 现在您可以使用IntegerString 的类型,这是Base 的两个构造函数。但它看起来并不能解决你的问题。
  • Martin O. 谈辅助构造函数here
  • 是的,我知道。我以前读过。但我的问题是关于案例类的。

标签: scala


【解决方案1】:

实际上它可以工作,但是您必须使用new,因为辅助构造函数没有为案例类生成apply

case class Something(s: String, n: Int, p: Int => Boolean) {
  def this(b: Boolean, x: Int, y: Int) {
    this("", 0, (i: Int) => i % x + y == 0)
  }
}

new Something(true, 5, 5) // Works

如果你想让Something(true, 5, 5) 工作,你需要按照你说的创建伴生对象。我认为这是因为否则 case 类将无法像现在这样使用模式匹配,否则它会复杂得多。请注意,在这种情况下模式匹配不起作用

还请记住,case 类支持默认构造函数,例如 case class Something(s: String = "default"),这可能会对您有所帮助,但不幸的是它并不能修复您的示例

【讨论】:

    猜你喜欢
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    相关资源
    最近更新 更多