2016-04-03 49 views
1

这是一个使用解释器GOF模式的aritmetic表达式求值器,BinaryOp是一个非终端表达式。为什么这个Java lambda表达式参数有错误?

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); 
    } 
} 

当定义双功能总和使用的λ,它的参数的错误,当我得到一个错误,如果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

您可以包括'Expression'的代码?我建议使用您的IDE将代码重构为匿名类,修复代码以便编译并重构它。 –

+6

对于你的最后一个问题:不要使用原始类型。 e1和e2应该是表达式,而不是表达式。对于错误:BiFunction接受两个参数,并返回结果。你的lambda需要3个参数:a,b和结果。 –

+0

@JB Nizet谢谢,我可以修正错误,只需使用lambda上的a和b,但对于最后一个问题,我将e1和e2更改为表达式,而且我仍然需要施放。 –

回答

0

Acording到JB Nizet评论这example我发现,我只需要使用A和B在lambda参数。

这里是正确的代码。

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); 
} 

和表达接口:

public interface Expression<T> { 

     public T interpret(IContext<T> context); 

} 

此错误是因为我参数化的诠释方法,这使得该方法返回的任何目的。我记得编译器输出错误“T#2与T#1类型不同”T#2是解释方法的通用参数< T>,T#1是类BinaryOpT>上的通用类型。

我不知道如何正确使用lambdas和泛型。

更新:修正了一些错误,我改变

public T interpret(IContext context); 

public T interpret(IContext<T> context); 
+0

其中一个问题是'IContext'与'IContext '不同# –

+0

是的,当我昨天测试我的代码时,我必须修正一些错误。 –

相关问题