Scala中的泛型:实现两次接口/特征?

Eyv*_*ind 12 c# java generics scala

给定一个通用接口,如下所示

interface I<T> {
    void m(T t);
}
Run Code Online (Sandbox Code Playgroud)

我可以在C#中创建一个类,它使用为T提供的不同类型实现两次(或更多次),例如

class C : I<int>, I<String> {
   public void m(int i) { }
   public void m(String s) { }
}
Run Code Online (Sandbox Code Playgroud)

由于擦除泛型类型信息,这在Java中无法完成,但是在Scala中可以实现这样的事情吗?

axe*_*l22 12

在同一性状号混合只可能在Scala中,如果2种类型与该性状(接口)与该类型的参数化符合对于彼此和所述性状是不是两次混合到同一类别直接.为了确保两种类型相互一致,通常必须使类型参数为covariant(+).

例如,这是不允许的:

scala> trait A[+T] { def foo: T = sys.error() }
defined trait A

scala> class C extends A[AnyRef] with A[String]
<console>:8: error: trait A is inherited twice
       class C extends A[AnyRef] with A[String]
Run Code Online (Sandbox Code Playgroud)

但这是:

scala> trait A[+T] { def foo: T = sys.error() }
defined trait A

scala> class C extends A[AnyRef]
defined class C

scala> class B extends C with A[String]
defined class B
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,您将不会像C#那样获得重载语义,但是重写语义 - A符合签名的所有方法将在一个具有最特定签名的方法中融合,根据线性化选择方法规则,而不是每次混合特征时都有一种方法.


Ale*_*nov 10

不,它不能.一般来说,我在这种情况下做的是

class C {
  object IInt extends I[Int] { ... }
  object IString extends I[String] { ... }
  ...
}
Run Code Online (Sandbox Code Playgroud)