Kotlin重载get/set后仍无法用方括号为二维数组赋值问题
问题原因
- 你在
Field类中重载的set/get运算符只属于Field类本身,只有直接对Field实例使用[]语法才会触发对应重载。你当前传给Player的是Field内部的原生二维数组Array<Array<String>>,Kotlin的原生二维数组本身不支持[a,b]的下标语法,仅支持[a][b]的写法,因此会报set函数参数过多。 - 额外注意:你当前代码中
Field类的field属性是private修饰的,外部无法直接访问,val player = Player(gameField.field)这行本身也会编译报错。
解决方案
推荐使用方案一,封装性更好,也能复用你已经写好的运算符重载逻辑:
方案一:直接传递Field实例给Player
- 给
Field类新增size属性,供外部获取数组尺寸 - 修改
Player的构造参数为Field类型,不再直接接收内部数组 - 修改
main函数中Player的实例化逻辑,直接传入Field实例
修改后完整代码
fun main() { val gameField = Field() gameField.buildField() // 直接传入Field实例 val player = Player(gameField) gameField.printField() var input: String? = " " while (input != "x") { println("w: ↑ a: ← s: ↓ d: →") input = readLine() when (input) { "w" -> player.counter = 0 "a" -> player.counter = 1 "s" -> player.counter = 2 "d" -> player.counter = 3 "x" -> return println("Spiel wird beendet") " " -> player.move() else -> println("Ungültige Eingabe") } player.setPlayer() gameField.printField() } } class Field() { private var field = Array(10) {Array(10){" "}} // 新增size属性对外暴露数组尺寸 val size get() = field.size operator fun set(row: Int, col: Int, value: String) { field[row][col] = value } operator fun get(row: Int, col: Int) = field[row][col] fun buildField() { for (i in field.indices) { field[i][0] = "# " field[i][field.size - 1] = "# " for (j in 1 until field.size - 1) { field[i][j] = " " field[0][j] = "# " field[field.size - 1][j] = "# " } } } fun printField() { for (i in field.indices) { for (j in field[i].indices) { print(field[i][j]) } println() } } } // 构造参数改为Field类型 class Player(private val gameField: Field) { private val playerSign = arrayOf<String>("↑ ", "← ", "↓ ", "→ ") var currentRow = 4 var currentColumn = 4 var counter = 0 init { setPlayer() } fun setPlayer() { // 直接调用Field重载的set运算符 gameField[currentRow, currentColumn] = playerSign[counter] } fun reset() { gameField[currentRow, currentColumn] = " " } fun move() { reset() when(counter) { 0 -> if (currentRow > 1) currentRow-- 1 -> if (currentColumn > 1) currentColumn-- 2 -> if (currentRow < gameField.size-2) currentRow++ 3 -> if (currentColumn < gameField.size-2) currentColumn++ } setPlayer() } }
方案二:不修改传参结构
如果不想调整现有传参逻辑,只需要做两处修改即可:
- 去掉
Field类中field属性的private修饰符,允许外部访问内部数组 - 把
Player类中所有gameField[a,b]的写法改为原生数组的gameField[a][b]格式
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

