为什么我必须将以下条件表达式的结果分配给变量才能使其编译?
piece.isWhite() ? whitePieceSquares.add(getSquare(pos)) : blackPieceSquares.add(getSquare(pos));
上面没有编译,下面是:
boolean garbage = piece.isWhite() ? whitePieceSquares.add(getSquare(pos)) : blackPieceSquares.add(getSquare(pos));
List#add()
返回一个布尔值,但我会忽略它。只是条件运算符的设计方式是必须分配从函数返回的值,那些返回函数必须具有相同的类型吗?
答案 0 :(得分:5)
来自section 14.8 of the JLS(表达式陈述):
某些类型的表达式可以通过以分号跟随它们来用作语句:
ExpressionStatement: StatementExpression ; StatementExpression: Assignment PreIncrementExpression PreDecrementExpression PostIncrementExpression PostDecrementExpression MethodInvocation ClassInstanceCreationExpression
通过计算表达式来执行表达式语句;如果表达式具有值,则丢弃该值。当且仅当表达式的评估正常完成时,表达式语句的执行才会正常完成。
与C和C ++不同,Java编程语言只允许某些形式的表达式用作表达式语句。
...
另一方面,该语言允许表达式语句中所有最有用的表达式,并且它不需要用作表达式语句的方法调用来调用void方法,因此几乎不需要这样的技巧。如果需要技巧,可以使用赋值语句(第15.26节)或局部变量声明语句(第14.4节)。
基本上,条件运算符的原则目标是评估它的操作数 - 你将它用于副作用。
Peter Lawrey的回答显示了一个更好的用法 - 你使用条件运算符来计算要添加该块的方块,然后在其上调用该方法。
答案 1 :(得分:4)
试
(piece.isWhite() ? whitePieceSquares : blackPieceSquares).add(getSquare(pos));
编辑:不确定为什么这是一个有效的声明。这是一个您应该能够编译/运行的简短示例。
boolean out = true;
(out ? System.out : System.err).println("Hello");
答案 2 :(得分:2)
在C中,这是可能的,因为你可以编写像
这样的东西void foo(int bar) {
bar;
}
在java中,你不能,我也不会错过它。但是,如果你出于某些原因不喜欢写作if ... else ...,那应该编译:
(piece.isWhite() ? whitePieceSquares : blackPieceSquares).add(getSquare(pos));
答案 3 :(得分:1)
基本上答案是:只是因为。 ?:
并且所有算术运算符只能出现在表达式的右侧。
答案 4 :(得分:0)
我猜你的add
函数返回一个布尔值。那些必须去哪儿,不是吗?