You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

  1. 给Field类新增size属性,供外部获取数组尺寸
  2. 修改Player的构造参数为Field类型,不再直接接收内部数组
  3. 修改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()
    }
}

方案二:不修改传参结构

如果不想调整现有传参逻辑,只需要做两处修改即可:

  1. 去掉Field类中field属性的private修饰符,允许外部访问内部数组
  2. 把Player类中所有gameField[a,b]的写法改为原生数组的gameField[a][b]格式

内容的提问来源于stack exchange,提问作者Fabian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 13:18:00