kotlin 接口中定义的扩展函数的可见性

问题描述 投票:0回答:1

我正在开发“15 人游戏”的示例项目。游戏板上的单元格定义为:

package board

enum class Direction {
    UP, DOWN, RIGHT, LEFT;
}

data class Cell(val i: Int, val j: Int) {
    override fun toString()= "($i, $j)"
}

interface SquareBoard {
    val width: Int

    fun Cell.getNeighbour(direction: Direction): Cell?
}

interface GameBoard<T> : SquareBoard {

    operator fun get(cell: Cell): T?
    operator fun set(cell: Cell, value: T?)

    fun find(predicate: (T?) -> Boolean): Cell?

}

我想从 GameOf15 类中的函数调用 Cell.getNeighbor 扩展函数

package games.gameOfFifteen

import board.Cell
import board.Direction
import board.GameBoard
import board.GameBoardImpl
import games.game.Game

class GameImpl(val initializer: GameOfFifteenInitializer) : Game
{
    val board:GameBoard<Int?>  = GameBoardImpl(4)

    override fun processMove(direction: Direction) {

        val openCell:Cell? = board.find { it == null}
        //this line does not compile
        val neighbor = openCell?.getNeighbor(direction)

    }
}

上面的代码无法编译。我收到错误“未解析的参考:getNeighbor”。我不确定我在这里做错了什么。我还需要做些什么才能使扩展功能可见吗?

kotlin inheritance interface extension-methods
1个回答
0
投票

任何不在顶层声明的扩展函数实际上都是成员函数。如果您转到 Tools -> Kotlin -> Show Kotlin Bytecode 然后单击 Decompile,您将看到如下内容:

在 Java 层面上,它只是一个成员函数,有一个额外的第一个参数

Cell
,它是 Kotlin 语法中的接收者。

因此,为了能够调用

cell.getNeighbour()
,您必须仅在实现
SquareBoard
的实例中执行此操作(即,如果
GameImpl
也实现了
SquareBoard
,那么从技术上来说它是可行的),或者将扩展函数移至顶级。

© www.soinside.com 2019 - 2024. All rights reserved.