编程语言
首页 > 编程语言> > java – 如何为泛型方法编写简洁的闭包?

java – 如何为泛型方法编写简洁的闭包?

作者:互联网

我想编写一个具有泛型方法的功能性非泛型接口的实现.实现需要内联闭包和简洁.

作为一个简化的例子

@FunctionalInterface interface Fn {
    <R> R fn(R arg);
}
public class Scratch {
    Fn id = arg -> arg;
    //Fn nul = arg -> null;
    //Fn requiresNonNull = ...
}

这使

/Scratch.java:5: error: incompatible types: invalid functional descriptor for lambda expression
    Fn id = arg -> arg;
            ^
    method <R>(R)R in interface Fn is generic
  where R is a type-variable:
    R extends Object declared in method <R>fn(R)
1 error

(实际上,参数将是具有返回类型为R的方法的通用接口.)

是否有一种解决方法而不回到匿名内部类的冗长?

有一个明显相似的问题,“Cannot convert functional interface with generic method into lambda expression”,但这源于使用一个名为Integer的类型参数而不是传统的类似T,而Jon Skeet接受的答案说他不知道我的问题的解决方案.

还有一个长期讨论,“Functional interface confusion”,未能回答这个问题.它不能是“一个冗长的匿名内部类最好在这里”,可以吗?

解决方法:

经过多次实验和间接后,我有一个解决方案.我在命名方面不太成功.

这是个主意

>功能接口和单个抽象方法都没有类型参数.
>功能接口接收具有类型参数但在方法参数中通配符的使用者.
>消费者只是一个内部的gubbins,但它确实有这个类型参数.它用于存储结果,而执行通过封闭函数返回.
>使用者自己接收包含实际业务功能实例的功能接口,该实例具有类型参数化类型.
>有一种将事物联系在一起的默认方法,包括创建消费者.

明确? [修辞]

因此,而不是能够写

Fn id = arg -> arg;

我们至少可以写

Fn id = q -> q.q(arg -> arg);

这是一家lambda lambda工厂.

我们似乎已经没有语法,也无法写出类似的内容

Fn id = Fn.Consumer::q(arg -> arg); // not valid syntax!

总共(主要显示我不作弊)

import java.util.concurrent.atomic.*;

@FunctionalInterface interface Fn {
    interface Instance<R> {
        R fn(R arg);
    }
    interface Consumer<R> {
       void q(Instance<R> gn);
    }

    void consume(Consumer<?> consumer);

    default <R> R fn(R arg) {
        AtomicReference<R> result = new AtomicReference<>();
        this.consume((Instance<R> instance) -> { result.set(instance.fn(arg)); });
        return result.get();
    }
}

public interface Scratch {
    Fn id = q -> q.q(arg -> arg);
    Fn nul = q -> q.q(arg -> null);

    public static void main(String[] args) {
        String idStr = id.fn("cruel");
        String nulStr = nul.fn("cruel");

        System.err.println(idStr);
        System.err.println(nulStr);
    }
}

我不认为我在类型系统中利用了任何缺乏稳健性.

(我应该在问题中添加一个更复杂的例子来说明你为什么要这样做.)

标签:java,lambda,generic-method,generic-lambda
来源: https://codeday.me/bug/20190705/1387790.html