创建泛型类(带通配符类型)和多个构造函数

时间:2011-03-17 09:44:24

标签: java scala

我对Scala(2.8)很陌生,这是我在Scala中难以表达的东西:

我需要定义一个类(由于与Java库的互操作性)实现了Comparable;它的泛型类型必须与自身或超类

进行比较

我还需要一个no-args构造函数和另一个使用泛型参数

的构造函数

我写了一个简单的相当于我想用Java获得的内容:

public class MyComparable<T extends Comparable<? super T>>{
    public MyComparable() {}

    public MyComparable(T a){
        System.out.println(a);
    }
}

我可以在scala REPL中导入这个类而没有任何问题,并实例化它。

这就是我在Scala中写的,试图完成同样的事情:

import java.lang.Comparable

class MyComparable[T <: Comparable[_>:Tb],Tb]()(implicit ev: T=:=Tb) {
    def this(a: T) = {
        this()
        println(a)
    }
}

我尝试使用no-args构造函数作为默认构造函数,或者使用带有T参数的构造函数:在两种情况下,我都在第5行得到error: could not find implicit value for parameter ev: =:=[T,Tb]

Afaik,=:=默认情况下是从scala.Predef导入的(事实上,此代码只能使用一个构造函数)

3 个答案:

答案 0 :(得分:3)

不完全确定你要做什么,但你可以这样做:

import java.lang.Comparable

class MyComparable[T <: Comparable[_>:Tb],Tb]()(implicit ev: T=:=Tb) {
  def this(a: T)(implicit ev: T=:=Tb) = {
    this()
    println(a)
  }
}

答案 1 :(得分:3)

你的问题过于复杂了 - 虽然如果Java有声明站点方差,那么很好,这会使所有这一切都没有用。无论如何,这是等效的代码:

class MyComparable[T <: Comparable[T2], T2 >: T]() {
    def this(a: T) = {
        this()
        println(a)
    }
}

假设这不使用原始类型,并且有两个类型参数而不是一个。然后,还有一个问题是你实际上试图用这个宣言完成什么。我想知道你真正想要的不是这个:

import scala.annotation.unchecked.uncheckedVariance
class MyComparable[-T <: Comparable[T @uncheckedVariance]]() {
    def this(a: T) = {
        this()
        println(a)
    }
}

我告诉Scala在我的危险中忽略上面的差异,因为我认为Comparable确实可以是反变体。以下代码表明确实如此:

scala> trait Cp[-T] {
     |   def compareTo(other: T): Int
     | }
defined trait Cp

scala> class MyComparable[-T <: Cp[T]] {
     | }
defined class MyComparable

答案 2 :(得分:2)

这仍然与我发布的Java代码不同,但它似乎比其他解决方案更接近,更清晰:

import java.lang.Comparable
class MyComparable[T <: Comparable[T]]() {
    def this(a: Comparable[_ >: T]) = {
        this()
        println(a)
    }
}

这里有一堆杂项链接,因为当我遇到这个问题时,我可能会帮助其他有类似问题的人:

When is @uncheckedVariance needed in Scala, and why is it used in GenericTraversableTemplate?

to understand what does =:= really do

http://programming-scala.labs.oreilly.com/ch12.html#VarianceUnderInheritance

http://www.scala-lang.org/node/129

Type erasure and other low-level details of the Java generics

http://www.scala-lang.org/node/124

http://scalada.blogspot.com/2008/01/existential-types.html

http://lamp.epfl.ch/~emir/bqbase/2007/06/13/existentials.html