返回存在类型是否有意义?

时间:2015-08-13 02:49:01

标签: scala existential-type

如果我定义一个返回存在类型的方法:

myX

如果我调用X[_],我会得到一个类型val y: Any = 123 myX.hello(y) // compilation error! 的值,但我无法传递任何内容:

Nothing

我只能传递val y: Nothing = ??? myX.hello(y) // compilable, but useless

require

因此,返回存在类型的方法没有意义吗?

2 个答案:

答案 0 :(得分:3)

scala> trait X[T] {
     |   def hello(x: T):Unit = println(x)
     | }
defined trait X

您对函数的定义:

scala> def myX: X[_] = new X[Any] {}
myX: X[_]

scala> val xnothing = myX
xnothing: X[_] = $anon$1@5c44c582

scala> xnothing.hello(1)
<console>:14: error: type mismatch;
 found   : Int(1)
 required: _$1
       xnothing.hello(1)
                      ^

“固定”相同功能的定义 - 正确捕获类型arg:

scala> def myY[T]: X[T] = new X[T] {}
myY: [T]=> X[T]

如果未通过通用arg,则推断Nothing

scala> val ynothing = myY
ynothing: X[Nothing] = $anon$1@53f0a4cb

您可以显式传递通用arg。

scala> val yint = myY[Int]
yint: X[Int] = $anon$1@555cf22

显然Int不是Nothing

scala> ynothing.hello(1)
<console>:14: error: type mismatch;
 found   : Int(1)
 required: Nothing
       ynothing.hello(1)
                      ^

这显然有效,因为我们明确地传递了Int

scala> yint.hello(1)
1

现在这是一个有趣的部分。它的工作原理是因为Scala可以发现泛型arg是Int(来自用法)。将其与上面的ynothing定义及其无法编译的调用ynothing.hello(1)进行对比。

scala> myY.hello(1)
1

答案 1 :(得分:3)

返回存在类型没有多大意义,但在其他情况下它们可能很有用。作为一个简单的例子

// method which returns an existential type
// note that you can't return Array[Any] here,
// because arrays aren't covariant in Scala (which is a good thing)
def array: Array[_] = if (some condition) Array[Int](...) else Array[Double](...) 

// all of following works
array(0)
array.length
// etc.

当然,如果你可以编写一个方法的精确泛型类型,你肯定会喜欢它。