7

例如,Exception.allCatch定义为

def allCatch[T]: Catch[T] 

为什么不只是

val allCatch: Catch[Nothing]

它的论点何时Catch是协变的?

或者,为什么PartialFunction对象定义

def empty[A, B]: PartialFunction[A, B] 

而不仅仅是

val empty: PartialFunction[Any,Nothing]

?

更新:到目前为止,答案似乎没有抓住重点。因此,请在您的答案中包含一个真正针对该问题的具体示例。例如:显示一段可以def empty[A, B]: PartialFunction[A, B]val empty: PartialFunction[Any,Nothing].

4

4 回答 4

2

PartialFunction 查看available here的来源,我们可以看到它实际上调用了PartialFunction对象的私有方法:

private[this] val empty_pf: PartialFunction[Any, Nothing]

所以空的返回类型将永远是PartialFunction[Any, Nothing]。至于背后的原因我不知道。也许其他人对原因有更好的了解。您也可以尝试语言邮件列表...

于 2013-03-10T12:50:27.360 回答
2

如果对类型进行硬编码,例如PartialFunction[Any,Nothing],则不能限制函数采用比 . 更具体的参数Any

通过使用泛型类型参数,您最终可以更灵活地满足所有情况,尤其是使函数安全。

假设您想要一个函数,其目标是采用Animalas 参数并返回Integer.

让我们假设函数被声明为:

def myFunction: PartialFunction[Any,Nothing]

首先, PartialFunction 不会专门用于Animal参数端,而是专门用于Any. 如果我传递一个Humanas 参数怎么办......,它会通过.. 安全呢?

其次,如果这个函数被声明为返回Nothing,你不能从它返回任何值,但是Nothing!事实上,Nothing它是 Scala 中所有类的子类。这导致了一个已知规则,即返回类型参数必须始终是协变的,以使函数有趣,而不是Nothing.

事实上,只有Nothing在处理empty. PartialFunction逻辑,因为根据定义,空PartialFunction不涉及任何返回,应该被迫这样做:)

你会问:“那我们为什么不把返回类型改成Any呢?” 答:因为您将失去通用擦除时间的所有好处,使编译器自动添加所需的强制转换=>您不会直接检索 Integer 值,而是 Any。恼人的..

于 2013-03-10T12:29:46.537 回答
2

这节省了稍后进行强制转换的需要,并允许将 args 类型视为 T 而不是 Any,这通常更方便。

这是一个例子:

scala> def func1[T](arg : T) : T = { arg }
func1: [T](arg : T)T

scala> def func2(arg : Any) : Any = { arg }
func2: (arg: Any)Any

scala> func1(4)
res4: Int = 4

scala> func2(4)
res7: Any = 4
于 2013-03-10T11:37:47.347 回答
1

实际上,似乎 Scala 标准库有更多的地方泛型类型参数是多余的(因为类型差异)。例如,请参阅我关于foreach. 根据@Peter 的回答,我的猜测是这些冗余的泛型使界面更加清晰。多亏了他们,我们不必记住哪些类型是协变的、逆变的和不变的。此外,对于不熟悉方差的人来说,这让事情变得更简单,这是 Scala 的一个高级特性。

于 2013-03-10T22:44:42.823 回答