【问题标题】:Trying to mimic java functional interface试图模仿java功能接口
【发布时间】:2021-12-17 14:32:24
【问题描述】:

我正在尝试通过编写以下代码来模仿 java 的 Function

interface SFunction<T, G> {
    G apply(T t);

    default <Q> SFunction<T, Q> andThen(SFunction<? super G, ? extends Q> after) {
       return (T t) -> {
            return after.apply(apply(t));
        };
        // return new SFunction<T, Q>() {
        // @Override
        // public Q apply(T t) {
        // return after.apply(apply(t));
        // }
        // };
    }
}

当我在andThen 中编写以下代码时,它工作正常(指向接口的apply(T t))并完美链接其他功能实现

snippet A return (T t) -> {
    return after.apply(apply(t));     
};

但是在sn-p下面写的时候,就陷入了递归,逻辑上是对的

snippet B return new SFunction<T, Q>() {
            @Override
            public Q apply(T t) {
                return after.apply(apply(t));
            }
        };

,但是为什么在 sn-p A 中,after.apply(apply(t)) 调用外部 apply(T t),即使内部 java 实现了匿名实现。

sn-p A 和 B 在内部和逻辑上不一样吗?

谢谢

【问题讨论】:

    标签: java lambda interface functional-programming functional-interface


    【解决方案1】:

    重要的是要注意sn-p B中的apply(t)实际上指的是什么方法:

    @Override
    public Q apply(T t) { // <--- it's referring to this method!
        return after.apply(apply(t));
    //                     ^^^^^^^^
    }
    

    它实际上是指apply(T) 方法,它返回您刚刚声明的Q。它试图递归调用它。但显然这不起作用,因为after.apply 并不期望QQ apply(T)方法的声明shadows外部声明的G apply(T)方法。

    在 lambda 的情况下,您没有引入名为 apply 的新标识符,因此 apply 只能表示 SFunction&lt;T, G&gt; 对象上的 apply - 即调用 andThen 的对象。

    要在SFunction&lt;T, Q&gt;匿名类中引用SFunction&lt;T, G&gt;对象的apply方法,可以使用限定的this表达式:

    return after.apply(SFunction.this.apply(t));
    

    SFunction.this 指的是调用andThenSFunction&lt;T, G&gt; 对象。

    现在这两个版本在逻辑上是相同的,但在内部,lambdas are very different from anonymous classes

    【讨论】:

      猜你喜欢
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 2010-10-09
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      相关资源
      最近更新 更多