【问题标题】:Overload private constructor with polymorphic arguments in Scala在 Scala 中使用多态参数重载私有构造函数
【发布时间】:2015-07-17 08:28:20
【问题描述】:

我很好奇 Scala 中最好的解决方案是什么:

class MyClass private (x: Any, y: Int) {
  def this(x: Int, y: Int) = this(x, y)
  def this(x: String, y: Int) = this(x, y)
}

val x0 = new MyClass(1, 1)
val x1 = new MyClass("1", 1)
//val x2 = new MyClass(1.0, 1) // Correctly doesn't typecheck

下面的错误对我来说没有多大意义,因为似乎在辅助构造函数之前定义了一个可行的构造函数:

Error:(3, 31) called constructor's definition must precede calling constructor's definition
  def this(x: Int, y: Int) = this(x, y)
                         ^

关于更多上下文,我实际上是在尝试处理 Scala.js 中的 JavaScript API,其函数采用的参数可以是 Stringjs.Object,但我认为这说明了这个问题。

【问题讨论】:

    标签: scala scala.js


    【解决方案1】:

    明确地将类型归属于Any 将有所帮助:

    class MyClass private (x: Any, y: Int) {
      def this(x: Int, y: Int) = this(x: Any, y)
      def this(x: String, y: Int) = this(x: Any, y)
    }
    

    在您的情况下,构造函数会递归调用自己,这显然是荒谬的。

    【讨论】:

    • ...我不知道我能做到这一点。我尝试了类似但更冗长的方法,但可能由于不相关的原因而失败。谢谢!
    【解决方案2】:

    我从未使用过 Scala-js,但这能解决您的问题吗:

    class MyClass private (x: Any, y: Int)
    
    object MyClass{
      def apply(x:Int,y:Int) = new MyClass(x,y)
      def apply(x:String, y:Int) = new MyClass(x,y)
    }
    
    
    val x0 = MyClass(1, 1)
    val x1 = MyClass("1", 1)
    //val x2 = new MyClass(1.0, 1) // Correctly doesn't typecheck
    

    【讨论】:

    • 这在 Scala 中确实是一个可行的选择。然而,OP 正在尝试为现有的 JavaScript 库 IIUC 创建一个外观。这意味着您在上面看到的代码仅用于输入目的,实际上并不生成任何内容。因此,OP 无法对其结构进行调整。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 2013-09-08
    • 2019-03-02
    相关资源
    最近更新 更多