简体   繁体   English

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

[英]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.

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