【发布时间】:2016-07-22 19:50:04
【问题描述】:
这是一个使用解释器 GOF 模式的算术表达式求值器,BinaryOp 是一个非终结表达式。
public class BinaryOP<T> implements Expression<T> {
private Expression<T> e1;
private Expression<T> e2;
private BiFunction<Expression<T>, Expression<T>, T> f;
public BinaryOp(Expression<T> e1, Expression<T> e2,
BiFunction<Expression<T>, Expression<T>, T> f){
this.e1 = e1; this.e2 = e2; this.f = f;
}
@Override
public <T> T interpret(IContext context){
return (T)f.apply(e1, e2);
}
}
而变量是终结表达式。
public class Variable<T> implements Expression<T> {
private T v;
public Variable(T v){
this.v = v;
}
@Override
public <T> T interpret(IContext context){
return (T)context.recognize(v);
}
}
在定义 BiFunction 总和时,我在使用 lambda 时出现错误,如果 a 和 b 是表达式类型并且结果返回整数,则其参数出现错误 ¿为什么会出现此错误?
public class AritmeticInterpreter
{
public static void main(String[] args) {
IContext<Integer> ctxArimetic = value -> value;
BiFunction<Expression<Integer>, Expression<Integer>, Integer> sum
//Error = incompatible types: incompatible parameter types in lambda expression
= (a, b, result) -> {
return (Integer)a.interpret(ctxArimetic) + (Integer)b.interpret(ctxArimetic);
};
}
}
是什么导致了这个错误,必须是返回类型另一个表达式? 如果我将解释方法的返回类型更改为表达式,我将无法像这样对两个表达式 a 和 b 求和:
(a, b) -> a + b
因为它们不是整数。
好吧,这不是标题的一部分,但是,¿我可以摆脱对方法的强制解释吗?我知道 java 编译器会删除泛型类型,但是,¿有办法吗?
更新:
这是表达式界面。
public interface Expression<T> {
public <T> T interpret(IContext context);
}
【问题讨论】:
-
您能否将
Expression的代码包含在内?我建议使用您的 IDE 将代码重构为匿名类,修复代码以便编译并重构回来。 -
最后一个问题:不要使用原始类型。 e1 和 e2 应该是 Expression
类型,而不是 Expression。对于错误: BiFunction 接受两个参数,并返回一个结果。您的 lambda 接受 3 个参数:a、b 和结果。 -
@JB Nizet 谢谢,我可以在 lambda 上仅使用 a 和 b 来修复错误,但是对于最后一个问题,我将 e1 和 e2 更改为 Expression
并且我仍然需要强制转换。 -
public <T> T interpret(IContext context){应该是public T interpret(IContext context){。 -
是的,它可以工作,我不必投射。谢谢。
标签: java generics lambda functional-programming