为啥这个 Java lambda 表达式参数有错误?
Posted
技术标签:
【中文标题】为啥这个 Java lambda 表达式参数有错误?【英文标题】:Why this Java lambda expression parameter has an error?为什么这个 Java lambda 表达式参数有错误? 【发布时间】: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 应该是 Expressionpublic <T> T interpret(IContext context)
应该是public T interpret(IContext context)
。
是的,它可以工作,我不必投射。谢谢。
【参考方案1】:
根据 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);
在表达式接口上:
public interface Expression<T>
public T interpret(IContext<T> context);
这个错误是因为我参数化了解释方法,这允许该方法返回任何对象。我记得编译器输出错误“T#2 is different from type T#1” T#2 is the generic parameter 我不知道如何正确使用 lambda 和泛型。 更新:修复一些错误,我改变了 到public T interpret(IContext context);
public T interpret(IContext<T> context);
【讨论】:
是的,昨天测试我的代码时,我必须修复一些错误。以上是关于为啥这个 Java lambda 表达式参数有错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Kotlin 不能推断以下 lambda 参数(在 Java -> Kotlin 转换之后)?
为啥将 lambda 传递给受约束的类型模板参数会导致“不完整类型”编译器错误?