【问题标题】:Java generic inference is too broad?Java 泛型推理过于宽泛?
【发布时间】:2016-06-06 12:52:54
【问题描述】:

我有 2 节课:

class M {
    public <R, A, T extends A> A walk(BiFunction<Widget, Integer, Stream<R>> walker, BiFunction<A, Stream<R>, T> accF, A acc, int level) {
        return accF.apply(acc, walker.apply(this, level));
    }
}

class N extends M {

    public Stream<M> getChildren() {return Stream.of(new M()...);}

    @Override
    public <RR, A, T extends A> T walk(BiFunction<Widget, Integer, Stream<RR>> walker, BiFunction<A, Stream<RR>, T> accF, A acc, int level) {
        return accF.apply(accF.apply(acc, walker.apply(this, level)), getChildren().map(o -> o.walk(walker, accF, acc, level + 1)));
    }
}

但是,编译器在o.walk(walker, accF, acc, level + 1)inference variable T has incompatible bounds: equality constraints: T upper bounds: A, Object, RR

为什么会这样,我该如何解决这个问题?

【问题讨论】:

  • 这是你如何让别人痛苦的方式吗?
  • @MuratK。呵呵 :) 好吧,也许它看起来有点复杂.. 但这只是一个递归树访问者.. 至于这里的类型,它在 Scala 编程中很常见.. 不被视为世界之外的东西.. Java 的 idk虽然..
  • 你能把它编译成 except 以解决问题中的实际错误吗? IE。 Widget... 是什么?
  • 我对这里的 lambda 语法不太熟悉,但如果我没记错的话,map() 方法应该返回一个 Stream&lt;RR&gt; 类型的值,因为这就是 accF 的定义方式。但是,由于您还将accF 传递给o.walk(),因此您正试图返回一个不适合的T 类型的值。

标签: java generics recursion lambda type-inference


【解决方案1】:

这是一些非常复杂的代码,我没有时间真正考虑它,但由于 getChildren() 返回任何 MN#walk 使用它自己的通用定义,编译器知道例如A 可以是不同的类型,对于子级和walk 具有不同的边界。

您可以尝试将泛型定义放在类级别,例如

class M <R, A, T extends A> { 
  public  A walk(...) { ... }
}

class N <RR, A, T extends A> extends M< RR, A, T> { 
  public Stream<M<RR, A, T>> getChildren() {...}
  public  A walk(...) { ... }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    相关资源
    最近更新 更多