当前位置: 首页 > 知识库问答 >
问题:

Kotlin泛型数组导致“不能将T用作具体化的类型参数,而是使用类”,但List不这样做

邵正雅
2023-03-14

我有一个包含T数组(或列表)和一些元数据的接口。

interface DataWithMetadata<T> {
    val someMetadata: Int
    fun getData(): Array<T>
}

如果我编写接口的最简单实现,我会在emptyarray()上得到一个编译错误:“不能将T用作具体化的类型参数,而是使用类。”

class ArrayWithMetadata<T>(override val someMetadata: Int): DataWithMetadata<T> {
    private var myData: Array<T> = emptyArray()

    override fun getData(): Array<T> {
        return myData
    }

    fun addData(moreData: Array<T>) {
        this.myData += moreData
    }
}
interface DataWithMetadata<T> {
    val someMetadata: Int
    fun getData(): List<T>
}

class ListWithMetadata<T>(override val someMetadata: Int): DataWithMetadata<T> {
    private var myData: List<T> = emptyList()

    override fun getData(): List<T> {
        return myData
    }

    fun addData(moreData: Array<T>) {
        this.myData += moreData
    }
}

额外的问题:我选择数组而不是列表的唯一原因是我经常看到Kotlin开发人员喜欢数组。是这样吗?如果是,为什么?

共有1个答案

巫马刚洁
2023-03-14

查看kotlin stdlib(jvm)中emptyarray()声明,我们注意到reificed类型参数:

public inline fun <reified @PureReifiable T> emptyArray(): Array<T>

reificed类型参数意味着您在编译时可以访问T的类,并且可以像T::class一样访问它。您可以在Kotlin引用中阅读更多关于reificed类型参数的信息。由于数组 编译为javat[],我们需要在编译时知道类型,因此使用reificed参数。如果您尝试编写一个没有reificed关键字的emptyArray()函数,您将得到一个编译器错误:

fun <T> emptyArray() : Array<T> = Array(0, { throw Exception() })

不能使用T作为具体化类型参数。改为使用类。

public fun <T> emptyList(): List<T> = EmptyList

来自Java和C++,我习惯于ArrayListstd::vector,以便更容易地使用这些数组。我现在使用kotlin已经有几个月了,在编写源代码时,我通常不会看到数组和列表之间有太大的区别。两者都有大量有用的扩展函数,它们的行为方式类似。然而,Kotlin编译器处理数组和列表非常不同,因为Java互操作性对Kotlin团队非常重要。我通常更喜欢使用列表,这也是我在你的情况下推荐的。

 类似资料:
  • 所以我有那个代码,我是通过上传到Imgur v3使用Javahttps错误得到的,我在第50行得到一个错误,因为“列表”告诉我 类型列表不是泛型的;它不能用参数参数化 我能做些什么来解决这个问题? 我正在使用http://hc.apache.org/httpclient-3.x/并希望使用v3 API将图像上传到imgur。 编辑:更改导入后,我现在收到这些错误。 这就解决了这个问题,但又给了我两

  • 我使用的是Azure.data.tables nuget包的12.0.0-beta.6。当我尝试调用TableClient.GetQueryAsync时,它会给出错误: “类型”T“必须是引用类型,才能将其用作泛型类型或方法”TableClient.GetEntityAsync(string,string,IEnumerable,CancellationToken)“中的参数”T“。” 我看不出我

  • 我想使用泛型类作为另一个泛型类的类型参数。 起初,我对类的定义是这样的: 然后我的需求发生了变化,我不得不为我的R类型使用包装器/持有者类 到目前为止,我的尝试:(给出编译时错误:

  • 问题内容: import java.awt.List; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStreamReader; import java

  • 我遇到了一个奇怪的行为,在类型为“具体化”的函数中使用Gson进行反序列化。仅当类型参数中涉及接口时才会发生这种情况。 采用以下代码: 第4行使用自定义扩展函数Gson。fromJson(json:String):T。 如果定义为具体化,则失败: 如果它被定义为普通类型参数,它就可以工作: (注意,使具体化在这里没有意义,只是想了解它在特殊用例中的影响) 使用具体化时的异常如下所示: