[英]What is the equivalent Scala code for this Imperative coding style?
Find below the imperative style code:在命令式样式代码下方找到:
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;
}
}
Here I am interested in knowing how to convert changes made to offset within the loop in a functional way, how to do early break from the loop etc.在这里,我想知道如何以功能方式转换对循环内偏移所做的更改,如何提前中断循环等。
This is a nice demonstration of one of Scala's great strengths - gradual, easy migration from imperative Java code to functional code.这很好地展示了 Scala 的一大优势——从命令式 Java 代码到函数式代码的逐步、轻松迁移。
To convert to Scala, you don't need to go 100% functional straight away.要转换为 Scala,您无需立即使用 100% 功能。 You can easily convert what you have to Scala as follows:
您可以轻松地将您拥有的内容转换为 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
}
}
Note we already have some small improvements in verbosity: no more ;
请注意,我们已经对详细程度进行了一些小的改进:没有了
;
s, no redundant type signatures, mutable variables converted to constants where possible, eliminated return statements and function brackets. s,没有多余的类型签名,可变变量在可能的情况下转换为常量,消除了返回语句和函数括号。 Note I changed the argument type of
piecesToPlace
to a scala list, you'll need to use the scala-java converters at the call site to make this compile.注意我将
piecesToPlace
的参数类型piecesToPlace
为scala 列表,您需要在调用站点使用scala-java 转换器来进行编译。
Next, we can start making this more functional... however, this function probably isn't the place you should start, as you are calling state-mutating functions in several places.接下来,我们可以开始让它更实用……然而,这个函数可能不是你应该开始的地方,因为你在几个地方调用状态变异函数。 For example, you could start with ChessLayout:
例如,您可以从 ChessLayout 开始:
chessLayout.removeChessPiece(chessPiece)
val placedOffset = chessLayout.placePieceInNextAvailablePosition(chessPiece, offset)
These methods mutate ChessLayout, which is not functional style.这些方法改变了 ChessLayout,它不是函数式风格。 You could modify
removeChessPiece
to return a new ChessLayout
with the piece removed, and placePieceInNextAvailablePosition
could return a tuple of (ChessLayout, Int)
.您可以修改
removeChessPiece
以返回移除棋子的新ChessLayout
,并且placePieceInNextAvailablePosition
可以返回(ChessLayout, Int)
的元组。 Once you have stopped any functions called from placePieceOnBoard
from mutating state, you can then convert it to functional style.一旦您停止了从
placePieceOnBoard
调用的任何函数的变异状态,您就可以将其转换为函数样式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.