英文:
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<Object, Object, Object> 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<T, U, V, R> {
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编码中的<
和>
还原为正常的尖括号,以使代码更易读。
英文:
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<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));
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论