【问题标题】:Difference between Any type and Generics in KotlinKotlin 中任何类型和泛型的区别
【发布时间】:2017-10-19 17:37:32
【问题描述】:

假设我有以下函数定义。

fun<T> parse(a: Any): T = when (a) {
    is String -> a
    else -> false
}

我猜它应该是有效的。但是,IntelliJ IDEA linter 显示类型不匹配错误

话虽如此,我会将解析函数的返回类型更改为 Any,对吗?那么,在 Kotlin 中使用 Any 类型和泛型有什么区别?在哪些情况下应该使用其中的每一个?

我确实阅读了以下question,但由于我是新手,我完全不了解 Kotlin 中的星形投影。

【问题讨论】:

标签: kotlin


【解决方案1】:

您的返回类型定义为T,但无法保证Ta:Any 相关。 T 可能比 Any 更严格,在这种情况下,您不能返回布尔值或您为 a 提供的任何内容。

通过将返回类型从 T 更改为 Any,以下方法将起作用:

fun<T> parse(a: Any): Any = when (a) {
    is String -> a
    else -> false
}

任何替代选项,如果你真的想返回类型 T:

inline fun<reified T> parse(a: Any): T? = when (a) {
    is T -> a
    else -> null
}

【讨论】:

    【解决方案2】:

    您的示例没有使用T,因此将其设为通用是无稽之谈。

    想一想:作为客户,您将某些内容放入函数中,例如一个 XML-ByteArray,该函数应该将其解析为一个 Object。调用函数你不想让它返回Any(铸造很烂),但希望函数返回解析对象的类型。这可以通过泛型来实现:

    fun <T> parse(xml: ByteArray): T {
         val ctx: JAXBContext = JAXBContext.newInstance()
         val any = ctx.createUnmarshaller().unmarshal(ByteArrayInputStream(xml))
         return any as T
    }
    
    val int = parse<Int>("123".toByteArray())
    val string = parse<String>("123".toByteArray())
    

    看看方法调用:你用泛型告诉你期望返回什么类型。该代码没有用处,只是为了让您了解泛型。

    【讨论】:

      【解决方案3】:

      我猜应该是有效的

      为什么会这样?您在一个分支中返回 String,在另一个分支中返回 Boolean。所以整个when 表达式的通用类型是Any,这就是编译器(和IDEA)所说的“找到”。您的代码还说它应该是T(这是“必需的”)。

      您的通用方法应该适用于任何T,例如对于Int,但Any 不是Int 的子类型,因此代码无效。

      那么,在 Kotlin 中使用 Any 类型和泛型有什么区别?

      这就像问“使用数字和文件有什么区别”:它们最初没有太多共同点。您使用泛型来编写可以与所有类型 T 一起工作的代码(或所有满足某些约束的类型);当您需要特定类型 Any 时,您可以使用 Any

      【讨论】:

      • 有没有AnyT一起使用的好例子?或者在 Kotlin 中泛型是完全可选的
      猜你喜欢
      • 2016-11-12
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 2013-09-26
      相关资源
      最近更新 更多