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

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


作为一个简化的例子


@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。)


有没有一种解决方法而不必回到匿名内部类的冗长之处?


有一个明显的类似的问题,“不能转换功能界面与通用方法引入lambda表达式”,但是从使用一个被称为类型参数茎Integer,而不是其他传统一样T,和乔恩斯基特的接受的答案说,他不知道解决我的问题。


还有一个很长的讨论,“功能接口混淆”,没有回答这个问题。不可能是“这里最好使用冗长的匿名内部类”,对吗?



幕布斯7119047
浏览 172回答 2
2回答

芜湖不芜

泛型 lambda 不合法,但泛型方法引用是合法的。您可以通过创建辅助方法来减少匿名类的冗长:public class Scratch {&nbsp; &nbsp; Fn id = Scratch::id;&nbsp; &nbsp; Fn nul = Scratch::nul;&nbsp; &nbsp; Fn requiresNotNull = Objects::requireNonNull;&nbsp; &nbsp; private static <R> R id(R arg) {&nbsp; &nbsp; &nbsp; &nbsp; return arg;&nbsp; &nbsp; }&nbsp; &nbsp; private static <R> R nul(R arg) {&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }}

慕的地10843

经过大量实验和间接操作后,我有了一个解决方案。我在命名方面不太成功。这是想法函数式接口和单个抽象方法都没有类型参数。函数式接口接收具有类型参数但在方法参数中使用通配符的使用者。消费者只是一块内部gubbins,但它确实具有该类型参数。它用于在执行通过封闭函数返回时存储结果。消费者本身接收一个包含实际业务功能实例的功能接口,该实例属于参数化类型。有一个默认方法可以将事物联系在一起,包括创建使用者。清除?【修辞】所以,而不是能够写Fn&nbsp;id&nbsp;=&nbsp;arg&nbsp;->&nbsp;arg;我们至少可以写Fn&nbsp;id&nbsp;=&nbsp;q&nbsp;->&nbsp;q.q(arg&nbsp;->&nbsp;arg);这是一个 lambda lambda 工厂。我们似乎语法用完了,不能写类似的东西Fn&nbsp;id&nbsp;=&nbsp;Fn.Consumer::q(arg&nbsp;->&nbsp;arg);&nbsp;//&nbsp;not&nbsp;valid&nbsp;syntax!总而言之(有一个主要表明我没有作弊)import java.util.concurrent.atomic.*;@FunctionalInterface interface Fn {&nbsp; &nbsp; interface Instance<R> {&nbsp; &nbsp; &nbsp; &nbsp; R fn(R arg);&nbsp; &nbsp; }&nbsp; &nbsp; interface Consumer<R> {&nbsp; &nbsp; &nbsp; &nbsp;void q(Instance<R> gn);&nbsp; &nbsp; }&nbsp; &nbsp; void consume(Consumer<?> consumer);&nbsp; &nbsp; default <R> R fn(R arg) {&nbsp; &nbsp; &nbsp; &nbsp; AtomicReference<R> result = new AtomicReference<>();&nbsp; &nbsp; &nbsp; &nbsp; this.consume((Instance<R> instance) -> { result.set(instance.fn(arg)); });&nbsp; &nbsp; &nbsp; &nbsp; return result.get();&nbsp; &nbsp; }}public interface Scratch {&nbsp; &nbsp; Fn id = q -> q.q(arg -> arg);&nbsp; &nbsp; Fn nul = q -> q.q(arg -> null);&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; String idStr = id.fn("cruel");&nbsp; &nbsp; &nbsp; &nbsp; String nulStr = nul.fn("cruel");&nbsp; &nbsp; &nbsp; &nbsp; System.err.println(idStr);&nbsp; &nbsp; &nbsp; &nbsp; System.err.println(nulStr);&nbsp; &nbsp; }}我认为我没有利用类型系统中的任何缺陷。(我可能应该在问题中添加一个更复杂的示例,以说明您为什么要这样做。)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java