2

我正在尝试将构造函数重载到一个类,以便它可以接受两种不同类型对象的列表:

class myClass(){
  var someStrings: List[String]=List[String]()
  println("hello!")

  def this(strings : List[String])={
    this()
    this.someStrings=strings
  }

  def this(ints: List[Int])={
    this()
    this.someStrings=ints.map(x => x.toString)
  }
}

在这种情况下,接受整数或字符串列表,并将字符串列表保存到变量 someStrings。上面的代码不起作用:

error: double definition:
constructor myClass: (strings: List[String])myClass at line 12 and
constructor myClass: (ints: List[Int])myClass at line 17
have same type after erasure: (strings: List)myClass
             def this(ints: List[Int])={
             ^

在scala中有更好的方法吗?(除了使用 List[Any] 和测试元素)

谢谢!

4

3 回答 3

5

在伴随对象上创建函数,这些函数以类型安全的方式为您构建,可以在编译时检查:

class myClass(){
  var someStrings: List[String]=List[String]()
  println("hello!")
}

object myClass {
  def fromStrings(strings: List[String]) = {
    val c = new myClass
    c.someStrings = strings
  }
  def fromInts(ints: List[Int]) = {
    val c = new myClass
    c.someStrings = ints.map(_.toString)
  }
}

object Usage {
  val c1 = myClass.fromStrings(List("a","b","c"))
  val c2 = myClass.fromInts(List(1,2,3))
}

我会敦促您避免一般重载,或在运行时检查类型,而您可以在编译时检查类型

于 2014-05-13T04:26:20.397 回答
2

这就是DummyImplicit

def this(strings: List[String])={
  this()
  this.someStrings=strings
}

def this(ints: List[Int])(implicit d: DummyImplicit)={
  this()
  this.someStrings=ints.map(x => x.toString)
}

这使得构造函数的签名(即 JVM 看到的)MyClass(List)和被擦除MyClass(List, DummyImplicit),因此允许重载。

但是,正如@stew 所说,在这种情况下避免重载可能是一个更好的主意。

于 2014-05-13T13:14:19.470 回答
1

除了其他答案之外,您可以做的另一件事是使用数组。数组的类型信息在运行时保存,因此您可以根据类型参数进行重载。

class myClass() {
  var someStrings: Array[String] = Array[String]()
  println("hello!")

  def this(strings: Array[String]) = {
    this()
    this.someStrings = strings
  }

  def this(ints: Array[Int])={
    this()
    this.someStrings = ints.map(x => x.toString)
  }
}

在我看来,数组未被充分利用

于 2014-05-13T04:28:51.427 回答