繁体   English   中英

这种命令式编码风格的等效 Scala 代码是什么?

[英]What is the equivalent Scala code for this Imperative coding style?

在命令式样式代码下方找到:

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

在这里,我想知道如何以功能方式转换对循环内偏移所做的更改,如何提前中断循环等。

这很好地展示了 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的参数类型piecesToPlace为scala 列表,您需要在调用站点使用scala-java 转换器来进行编译。

接下来,我们可以开始让它更实用……然而,这个函数可能不是你应该开始的地方,因为你在几个地方调用状态变异函数。 例如,您可以从 ChessLayout 开始:

chessLayout.removeChessPiece(chessPiece)

val placedOffset = chessLayout.placePieceInNextAvailablePosition(chessPiece, offset)

这些方法改变了 ChessLayout,它不是函数式风格。 您可以修改removeChessPiece以返回移除棋子的新ChessLayout ,并且placePieceInNextAvailablePosition可以返回(ChessLayout, Int)的元组。 一旦您停止了从placePieceOnBoard调用的任何函数的变异状态,您就可以将其转换为函数样式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM