如何在Kotlin中创建一个充满空值的泛型数组?

 呦呦嘉宾 发布于 2023-02-13 19:40

我试过这个,代码没有编译.

class GenericClass() {
    private var arr : Array? = null

    {
        arr = Array(10, { null })
    }
}

Andrey Bresl.. 17

此代码中报告了两个编译器错误:一个是关于可空类型,另一个是关于泛型.

可空类型.Kotlin强制执行可空引用的规则,并且因为T可以实例化,例如,String make arr是Array类型,编译器不允许将空值放入此数组中.如果需要空值,则必须将类型更改为Array:

class GenericClass() {
    private var arr : Array? = null

    {
        arr = Array(10, { null }) // No need to specify type arguments again
    }
}

泛型.上面的示例仍然存在编译时错误,因为我们正在尝试构造一个未知类型为T的数组.请注意,此问题也存在于Java中.编译为JVM字节代码的Kotlin需要两件事:

泛型类型参数在运行时被擦除,

除了数组的泛型参数.

这意味着在字节代码中,Kotlin必须创建一个具体类型的数组,而不是未知类型T.它可以在看到Array时创建对象数组,但这不起作用,例如,在这种情况下:

fun test() {
    fun foo(srts: Array) {
        // ...
    }
    val gc = GenericClass()
    foo(gc.arr)
}

这里,在最后一行,我们试图传递Object [],其中String []是预期的,并获得运行时错误.

这就是Kotlin拒绝创建T数组的原因.您可以通过显式地抑制类型系统来解决这个问题,即使用类型转换:

class GenericClass() {
    val arr : Array

    {
        arr = Array(10, { null }) as Array
    }
}

在这里,我们显式请求创建一个Any数组(编译为Object []),然后将其类型转换为T数组.编译器发出警告,但遵守我们的意愿.

请注意,上面的问题示例仍然存在,即如果您传递以预期字符串数组的方式创建的数组,则在运行时会失败.

1 个回答
  • 此代码中报告了两个编译器错误:一个是关于可空类型,另一个是关于泛型.

    可空类型.Kotlin强制执行可空引用的规则,并且因为T可以实例化,例如,String make arr是Array类型,编译器不允许将空值放入此数组中.如果需要空值,则必须将类型更改为Array:

    class GenericClass<T>() {
        private var arr : Array<T?>? = null
    
        {
            arr = Array(10, { null }) // No need to specify type arguments again
        }
    }
    

    泛型.上面的示例仍然存在编译时错误,因为我们正在尝试构造一个未知类型为T的数组.请注意,此问题也存在于Java中.编译为JVM字节代码的Kotlin需要两件事:

    泛型类型参数在运行时被擦除,

    除了数组的泛型参数.

    这意味着在字节代码中,Kotlin必须创建一个具体类型的数组,而不是未知类型T.它可以在看到Array时创建对象数组,但这不起作用,例如,在这种情况下:

    fun test() {
        fun foo(srts: Array<String?>) {
            // ...
        }
        val gc = GenericClass<String>()
        foo(gc.arr)
    }
    

    这里,在最后一行,我们试图传递Object [],其中String []是预期的,并获得运行时错误.

    这就是Kotlin拒绝创建T数组的原因.您可以通过显式地抑制类型系统来解决这个问题,即使用类型转换:

    class GenericClass<T>() {
        val arr : Array<T?>
    
        {
            arr = Array<Any?>(10, { null }) as Array<T?>
        }
    }
    

    在这里,我们显式请求创建一个Any数组(编译为Object []),然后将其类型转换为T数组.编译器发出警告,但遵守我们的意愿.

    请注意,上面的问题示例仍然存在,即如果您传递以预期字符串数组的方式创建的数组,则在运行时会失败.

    2023-02-13 19:42 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有