首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala:为什么PECS原则不适用于Function1?

Scala:为什么PECS原则不适用于Function1?
EN

Stack Overflow用户
提问于 2012-06-30 16:51:52
回答 2查看 452关注 0票数 3

在Effective Java中,Joshua Bloch讨论了PECS (生产者-扩展,消费者-超级)的原理。

我对此的理解是,为了增加API的灵活性,输入(产生的集合)应该是协变的,而输出(消费的集合)应该是逆变的。

实现此原则的函数可以具有以下签名:

代码语言:javascript
复制
private static void func( ArrayList<? extends Object> input, ArrayList<? super Integer> output)

然而,在Scala中,Function1特征有以下签名:

代码语言:javascript
复制
trait Function1[-T1, +R] extends AnyRef

T1 (输入类型)是逆变的,而R(输出类型)是协变的。

我的理解正确吗?如果是这样的话,为什么在Scala的Function1特性中没有应用PECS呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-01 10:35:27

Joshua是正确的,Scala也是正确的。实际上,Scala强制执行此规则,因此您无需担心。Java没有变化注解,只能在调用点凑合使用,所以需要它们来指导程序员进行正确的设计。

Scala在定义位置有变化注释,而java在调用位置有存放点。调用的输出是定义的输入,反之亦然。

Function1不会读取参数,也不会写入结果,而这正是reduce在Joshua的示例中所做的。相反,您必须将Function1视为一个集合。

当您写入集合时,该集合就是使用者。类似于函数:当你调用它的时候,你就是在写它。因此,正在写入的输入参数必须是反向变量。

同样,当您从一个集合中读取时,该集合就是一个生产者。您可以通过查看结果来读取函数,因此输出参数必须是协变的。

如您所见,这正是Function1表示法。

票数 6
EN

Stack Overflow用户

发布于 2012-06-30 18:33:07

func上的通配符适用于传递给该方法的类型。它们意味着可以为输入传递任何ArrayList,并且可以为输出传递ArrayList<Object>ArrayList<Number>ArrayList<Integer>。该方法本身不是泛型的。

对于scala Function1类型,差异应用于该类型,因此可以在需要Function1[AnyRef, Integer]的地方使用Function[AnyRef, Number]

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11272819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档