Scala数独校验代码报illegal start of statement错误如何解决
问题修复方案
报错根本原因
你遇到的error: illegal start of statement (no modifiers allowed here)错误是因为:Scala 不允许给函数内部定义的嵌套方法加private访问修饰符,private只能用于类、单例对象的成员属性/方法,函数内部定义的方法天然只在当前函数作用域内可见,不需要也不能加访问修饰符。
其他隐含错误
你在validate方法内部定义了BoardParser单例对象,调用它的getValidBoard方法时没有加对象前缀,会报方法不存在的错误。
修复后完整代码
def validate(lines: Array[Option[Any]]*): Boolean = { object BoardParser { /** * 从可变参数解析数独棋盘 * 合法棋盘要求9行9列,非空单元格的值只能是Int或Long类型 * * @param board 可变参数,每个参数是可选值数组 * @return 代表数独棋盘的二维Int数组,空单元格用0表示 */ def getValidBoard(board: Array[Option[Any]]*): Array[Array[Int]] = { def validateBoard() = { if (board.length != 9 || board.transpose.length != 9) { throw new IllegalArgumentException("棋盘必须是9x9的二维数组") } else if (!board.forall(isAllNumbers)) { throw new IllegalArgumentException("棋盘非空值只能是Int或Long类型") } } validateBoard() board.map(toNumbers).toArray } private def isAllNumbers(line: Array[Option[Any]]) = { line.forall { case Some(_: Int) => true case Some(_: Long) => true case None => true case _ => false } } private def toNumbers(line: Array[Option[Any]]) = { line.map { case Some(x: Int) => x case Some(x: Long) => x.toInt case None => 0 case _ => throw new IllegalArgumentException } } } // 调用BoardParser的方法需要加对象前缀 val valid_board = BoardParser.getValidBoard(lines) def new_validate(board: Array[Array[Int]]): Boolean = { lazy val rowsValid = board.forall(hasNoDuplicates) lazy val columnsValid = board.transpose.forall(hasNoDuplicates) lazy val cellsValid = squaresHaveNoDuplicates(board) rowsValid && columnsValid && cellsValid } // 去掉private修饰符 def hasNoDuplicates(line: Array[Int]) = line.distinct.count(1 to 9 contains _) == line.count(_ != 0) // 去掉private修饰符 def squaresHaveNoDuplicates(matrix: Array[Array[Int]]) = { val rowBlocks = matrix.grouped(3).toArray val transposed = rowBlocks.map(_.transpose) val squares = transposed.map(_.grouped(3).toArray) val squaresFlattened = squares.map(_.map(_.flatten)) squaresFlattened.forall(_.forall(hasNoDuplicates)) } new_validate(valid_board) }
改动说明
- 移除了嵌套方法
hasNoDuplicates、squaresHaveNoDuplicates前面的private修饰符 - 调用
getValidBoard时增加了BoardParser.前缀,正确引用内部对象的方法 - 去除了多余的
return关键字,Scala 函数最后一行表达式的值默认就是返回值
内容的提问来源于stack exchange,提问作者Shiva ParsaRad
相关产品推荐
相关产品推荐

