【发布时间】:2019-05-26 18:56:29
【问题描述】:
我正在开发一个大量使用函数式接口的库,目前正在努力是否应用PECS:
Predicate<A>
Function<A,B>
BiFunction<A,B,C>
对比
Predicate<? super A>
Function<? super A, ? extends B>
BiFunction<? super A,? super B,? extends C>
它看起来很混乱,甚至错误消息都来自:
Incompatible types: Function<Item, Long> is not convertible to Function<Item, String>
类似
Incompatible types:
Function<capture of ? super Item, capture of ? extends Long> is not
convertible to Function<capture of ? super Item, capture of ? extends String>
这很难读。我已经阅读了following question,但仍然很难应用它,因为它会污染库代码并恶化编译器错误消息。我个人会为Predicate<A> 变体选择PCES。
是否有一些关于是否应用 PECS 的指导方针?我知道利弊,但我想知道人们真正存储的频率是多少。 Predicate 作为 lamdas 和方法引用的字段不受 PECS 提供的影响。我没有在网上找到任何进一步的建议。 Here 是受此影响的类之一。
【问题讨论】:
-
链接的答案说明了一切 - 您可能认为您不需要它或实际上找到了它的用例目前,但经验表明一些用户使用您的从长远来看,图书馆可能会恨你。奇怪的是,作为基于意见的 btw 关闭,我不认为它是这样的......
-
并不是那么简单:PECS 降低了库的可读性,对于一般知识很少的用户可能会被类型参数的巨大长度所迷惑,这使得推断函数的作用变得更加困难(它的签名是不容易理解),我们得到更糟糕的错误信息。受其影响的用户仍然可以做
t -> mismatchPredicate.test(t) -
对泛型知识很少的用户不应该从使用泛型库开始——而是学习泛型;这对我来说是一个非常糟糕的论点。
-
这个问题也可以从不同的角度来看待:因为 jdk 库使用 PECS,当然,用户可能在使用
? extends/super时甚至没有意识到为什么会这样 - 你可能会破坏他们的对此的看法。你不能让每个人都开心。 -
有趣的事实:即使是 OpenJDK 核心开发人员有时也会得到这个wrong。
标签: java java-8 functional-programming pecs