在下面找到命令式样式代码:
private boolean placePieceOnBoard(Results results,
ChessLayout chessLayout,
List<ChessPiece> piecesToPlace,
int pieceIndex,
int startOffset) {
if(pieceIndex == piecesToPlace.size()) {
results.addLayout(chessLayout);
return true;
}
else {
ChessPiece chessPiece = piecesToPlace.get(pieceIndex);
int offset = startOffset;
while(offset < chessLayout.getBoardLength()) {
int placedOffset = chessLayout.placePieceInNextAvailablePosition(chessPiece, offset);
if( placedOffset == ChessLayout.NULL_OFFSET )
break;
else {
logger.debug("piece {} ({}) moved", pieceIndex, chessPiece);
placePieceOnBoard(results, chessLayout.clone(), piecesToPlace, pieceIndex + 1, placedOffset + 1);
chessLayout.removeChessPiece(chessPiece);
offset = placedOffset + 1;
}
}
return false;
}
}
在这里,我有兴趣了解如何在循环中以功能方式转换对偏移的更改,如何从循环中进行早期中断等。
答案 0 :(得分:1)
这是Scala强大优势之一的一个很好的演示 - 从命令式Java代码到功能代码的逐步,轻松迁移。
要转换为Scala,您不需要立即100%运行。您可以轻松地将所有内容转换为Scala,如下所示:
def placePieceOnBoard(results: Results,
chessLayout: ChessLayout,
piecesToPlace: List[ChessPiece],
pieceIndex: Int,
startOffset: Int) {
if (pieceIndex == piecesToPlace.size()) {
results.addLayout(chessLayout)
true
}
else {
val chessPiece = piecesToPlace.get(pieceIndex)
var offset = startOffset
while(offset < chessLayout.getBoardLength) {
val placedOffset = chessLayout.placePieceInNextAvailablePosition(chessPiece, offset)
if( placedOffset == ChessLayout.NULL_OFFSET )
break
else {
logger.debug("piece {} ({}) moved", pieceIndex, chessPiece)
placePieceOnBoard(results, chessLayout.clone(), piecesToPlace, pieceIndex + 1, placedOffset + 1)
chessLayout.removeChessPiece(chessPiece)
offset = placedOffset + 1
}
}
false
}
}
请注意,我们在详细程度方面已有一些小的改进:不再有;
s,没有冗余类型签名,可变变量在可能的情况下转换为常量,消除了返回语句和函数括号。注意我将piecesToPlace
的参数类型更改为scala列表,您需要使用调用站点上的scala-java converters进行编译。
接下来,我们可以开始使它更具功能......但是,这个功能可能不是你应该开始的地方,因为你在几个地方调用状态变异函数。例如,您可以从ChessLayout开始:
chessLayout.removeChessPiece(chessPiece)
val placedOffset = chessLayout.placePieceInNextAvailablePosition(chessPiece, offset)
这些方法改变了ChessLayout,这不是功能风格。您可以修改removeChessPiece
以返回删除该部分的新ChessLayout
,placePieceInNextAvailablePosition
可以返回(ChessLayout, Int)
的元组。一旦停止从placePieceOnBoard
调用的任何函数处于变异状态,就可以将其转换为函数样式。