【发布时间】:2015-07-14 23:14:58
【问题描述】:
以下签名在 Scala 中有效且常用:
trait Collection[A] {
def reduceLeft [B >: A] (f: (B, A) => B): B
}
但是,由于>: 是 Java 中 super 的 Scala 等价物,我转换此签名的第一个想法(将函数类型替换为 BiFunction 并使用 Use-Site 差异注释,即有界通配符)将是
interface Collection<A> {
<B super A> B reduceLeft(BiFunction<? super B, ? super A, ? extends B> mapper)
}
但是哦不!编译器抱怨<B super A> 中的super 标记,因为你不能有下界类型变量!现在,我如何在 Java 代码中编写这个方法,而不必穿越到 Java 世界中不存在泛型的时候?
是的,我知道你认为我可以使用B extends A,但那不是一回事,正如我的实现所示:
public <R extends E> R reduceLeft(BiFunction<? super R, ? super E, ? extends R> mapper)
{
if (this.isEmpty())
{
return null;
}
Iterator<E> iterator = this.iterator();
R first = iterator.next(); // doesn't work, but would if R was a super-type of E (R super E)
while (iterator.hasNext())
{
mapper.apply(first, iterator.next());
}
return first;
}
相反,我不得不使用这个稍微受限的版本:
public E reduceLeft(BiFunction<? super E, ? super E, ? extends E> mapper)
{
if (this.isEmpty())
{
return null;
}
Iterator<E> iterator = this.iterator();
E first = iterator.next();
while (iterator.hasNext())
{
first = mapper.apply(first, iterator.next());
}
return first;
}
【问题讨论】:
-
首先,您没有声明
A类型参数。所以我把它改写为<A, B super A> B reduceLeft(BiFunction<? super B, ? super A, ? extends B> mapper)。但这仍然行不通。不过,它确实适用于extends。于是我想,B super A和A extends B一样吗?我认为它们是一样的...所以你可以写<B, A extends B> B reduceLeft(BiFunction<? super B, ? super A, ? extends B> mapper)
标签: java scala bounded-wildcard type-variables