这是一个使用解释器GOF模式的aritmetic表达式计算器,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编译器会删除泛型类型,但是,有没有办法?
更新
这是Expression界面。
public interface Expression<T> {
public <T> T interpret(IContext context);
}
答案 0 :(得分:0)
根据JB Nizet评论和example我发现我只需要在lambda中使用a和b作为参数。
这是正确的代码。
public static void main(String[] args) {
IContext<Integer> ctxArimetic = value -> value;
BiFunction<Expression<Integer>, Expression<Integer>, Integer> sum
= (a, b) -> {
return a.interpret(ctxArimetic) + b.interpret(ctxArimetic);
};
}
以及最后一个问题。
在BinaryOP类上我做了这个改变:
@Override
public T interpret(IContext<T> context){
return f.apply(e1, e2);
}
并在Expression接口上:
public interface Expression<T> {
public T interpret(IContext<T> context);
}
这个错误是因为我参数化了解释方法,这允许该方法返回任何对象。我记得编译器输出错误“T#2与类型T#1不同”T#2是通用参数&lt; T&gt;关于解释方法和T#1是类BinaryOp&lt; T&gt;上的泛型类型。
我不知道如何正确使用lambdas和泛型。
更新:修正了一些错误,我改了
public T interpret(IContext context);
要
public T interpret(IContext<T> context);