在Scala中使用通配符

时间:2015-09-22 15:50:32

标签: scala

假设:

scala> trait Thingy[A] {}
defined trait Thingy

之间有什么区别:

scala> def f[A](x: Thingy[A]): Thingy[A] = x
f: [A](x: Thingy[A])Thingy[A]

scala> def g(x: Thingy[_]): Thingy[_] = x
g: (x: Thingy[_])Thingy[_]

以下显示了一个区别:

scala> def foo[A](x: Thingy[A]): Thingy[A] = f(x)
foo: [A](x: Thingy[A])Thingy[A]

scala> def bar[A](x: Thingy[A]): Thingy[A] = g(x)
<console>:24: error: type mismatch;
 found   : Thingy[_$2] where type _$2
 required: Thingy[A]
       def bar[A](x: Thingy[A]): Thingy[A] = g(x)
                                              ^

但是,请解释fg之间的区别。

2 个答案:

答案 0 :(得分:3)

g的等效语法为:

def g[A, B](x: Thingy[A]): Thingy[B] = x

...除了抱怨因为AB不等同。使用_,您告诉编译器放弃有关AB的任何信息。因此,无法证明barg的输入类型与输出的类型相同。

答案 1 :(得分:3)

g的类型说:给定Thingy带有某个类型参数,它会返回一个带有一些(可能是不同的)类型参数的Thingy。例如。这将是一个合法的实施:

def g(x: Thingy[_]): Thingy[_] = new Thingy[Int] {}

现在很明显,bar无法使用g的定义,因为无论Thingy[Int]如何,它都会返回A。由于编译器仅使用g(不是实现)的类型,因此必须拒绝bar