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

Kotlin如何传递泛型类型接收者 调用时出现Player/NPC类型不匹配错误

问题根本原因

你触发类型不匹配的核心原因是:Kotlin 编译器无法识别你写的checkPlayers、checkNpcs运行时类型校验逻辑和泛型T的关联关系。你传入的chunk.players是固定List<Player>类型、chunk.npcs是固定List<NPC>类型,而你的function参数类型是(T) -> Boolean,编译器没法确认当前分支下T和Player/NPC的类型兼容关系,所以直接抛出类型不匹配错误。

解决方案

因为你已经提前做了运行时的类型校验,进入对应分支时T必然和Player/NPC类型兼容,所以只需要对function做一次强制类型转换,同时加注解忽略编译器的未检查转换警告即可,修改后的核心代码如下:

inline fun <reified T : Entity> forEach(
    position: Position,
    radius: Int,
    function: (entity: T) -> Boolean
) {
    val radiusChunkSize = ceil((radius / 8.0f).toDouble()).toInt()
    val fullWidth = radiusChunkSize shl 3
    val centerX: Int = position.x
    val centerY: Int = position.y
    val centerZ: Int = position.height
    val checkPlayers = T::class.java.isAssignableFrom(Player::class.java)
    val checkNpcs = T::class.java.isAssignableFrom(NPC::class.java)
    val startX = max(0, centerX - fullWidth)
    val startY = max(0, centerY - fullWidth)
    val endX = max(0x3FFF, centerX + fullWidth)
    val endY = max(0x3FFF, centerY + fullWidth)
    for (x in startX..endX step 8) {
        for (y in startY..endY step 8) {
            val chunk = ChunkManager[Position(x, y, centerZ)] ?: continue
            if (checkPlayers) {
                @Suppress("UNCHECKED_CAST")
                if (!forEach(radius, chunk.players, position, function as (Player) -> Boolean)) return
            }
            if (checkNpcs) {
                @Suppress("UNCHECKED_CAST")
                if (!forEach(radius, chunk.npcs, position, function as (NPC) -> Boolean)) return
            }
        }
    }
}

这种写法是完全安全的,因为你已经通过isAssignableFrom保证了只有当T是Player/Player的父类时才会进入对应分支,强转不会出现类型转换异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:36:04