回调函数带有3个参数。

huangapple go评论68阅读模式
英文:

Callback with 3 parameters

问题

在现代的Java中,使用回调(也称为函数引用或函数指针)处理最多两个参数非常简单和直观。示例如下:

class a {
  public static Object plus(Object a, Object b) {
    return (Double) a + (Double) b;
  }

  public static void main(String[] args) {
    BiFunction<Object, Object, Object> f = a::plus;
    System.out.println(f.apply(2.0, 3.0));
  }
}

(参数和返回值可以有类型,但它们必须是对象引用,而不是原始类型。)

编译器直接了解java.util.function.BiFunction及其较小的相关类,如上述main方法的反汇编所示:

0: invokedynamic #17,  0             // InvokeDynamic #0:apply:()Ljava/util/function/BiFunction;
5: astore_1
6: getstatic     #21                 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: ldc2_w        #27                 // double 2.0d
13: invokestatic  #13                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
16: ldc2_w        #29                 // double 3.0d
19: invokestatic  #13                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
22: invokeinterface #31,  3           // InterfaceMethod java/util/function/BiFunction.apply:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
27: invokevirtual #36                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
30: return

然而,没有java.util.function.TriFunction

如何设置具有三个参数的回调呢?

英文:

In modern Java, using a callback (a.k.a. function reference a.k.a. function pointer) with up to two parameters is pleasantly easy and straightforward. Example:

class a {
  public static Object plus(Object a, Object b) {
    return (Double) a + (Double) b;
  }

  public static void main(String[] args) {
    BiFunction&lt;Object, Object, Object&gt; f = a::plus;
    System.out.println(f.apply(2.0, 3.0));
  }
}

(The parameters and return value can be typed, though they have to be object references, not primitives.)

The compiler directly knows about java.util.function.BiFunction and its smaller kin, as can be seen in the disassembly of the above main:

     0: invokedynamic #17,  0             // InvokeDynamic #0:apply:()Ljava/util/function/BiFunction;
     5: astore_1
     6: getstatic     #21                 // Field java/lang/System.out:Ljava/io/PrintStream;
     9: aload_1
    10: ldc2_w        #27                 // double 2.0d
    13: invokestatic  #13                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
    16: ldc2_w        #29                 // double 3.0d
    19: invokestatic  #13                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
    22: invokeinterface #31,  3           // InterfaceMethod java/util/function/BiFunction.apply:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
    27: invokevirtual #36                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
    30: return

There is, however, no java.util.function.TriFunction.

How do you set up a callback with three parameters?

答案1

得分: 3

只需创建您自己的TriFunction函数式接口。让我们保持简单,暂时省略所有默认方法:

@FunctionalInterface
interface TriFunction<T, U, V, R> {

    R apply(T t, U u, V v);
}

注解是可选的,但如果您添加另一个非默认方法,它将导致编译器错误。

英文:

Just create your own TriFunction functional interface. Let's keep it simple and omit all the default methods for now:

@FunctionalInterface
interface TriFunction&lt;T, U, V, R&gt; {

    R apply(T t, U u, V v);
}

The annotation is optional, but it will cause a compiler error if you add another non-default method.

答案2

得分: 1

从函数式编程的角度来看,你可以使用柯里化来解决这个问题。这意味着你的函数会返回另一个函数。你可以将这个函数传递给方法(或其他函数)。

以下是使用柯里化的示例代码:

import java.util.function.Function;

public class A {

    public static Function<Double, Function<Double, Function<Double, Double>>> plus = a -> b -> c -> a + b + c;
    public static Function<Double, Function<Double, Function<Double, Double>>> multiply = a -> b -> c -> a * b * c;

    public static double doMath(double a, double b, double c, Function<Double, Function<Double, Function<Double, Double>>> calc) {
        return calc.apply(a).apply(b).apply(c);
    }

    public static void main(String[] args) {
        System.out.println("Plus:     " + doMath(2, 3, 4, plus));
        System.out.println("Multiply: " + doMath(2, 3, 4, multiply));
    }
}

请注意,我已经将HTML编码中的&lt;&gt;还原为正常的尖括号,以使代码更易读。

英文:

From a functional programing perspective you solve this with currying. Meaning your function return another function. You can pass the Function to methods (or other functions).

Here is your example with currying:

import java.util.function.Function;

public class A {

    public static Function&lt;Double, Function&lt;Double, Function&lt;Double, Double&gt;&gt;&gt; plus = a -&gt; b -&gt; c -&gt; a + b + c;
    public static Function&lt;Double, Function&lt;Double, Function&lt;Double, Double&gt;&gt;&gt; multiply = a -&gt; b -&gt; c -&gt; a * b * c;

    public static double doMath(double a, double b, double c, Function&lt;Double, Function&lt;Double, Function&lt;Double, Double&gt;&gt;&gt; calc) {
        return calc.apply(a).apply(b).apply(c);
    }

    public static void main(String[] args) {
        System.out.println(&quot;Plus:     &quot; + doMath(2, 3, 4, plus));
        System.out.println(&quot;Multiply: &quot; + doMath(2, 3, 4, multiply));
    }
}

huangapple
  • 本文由 发表于 2023年1月9日 12:06:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75053100.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定