是否可以在when语句中返回与type参数相同的类型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以在when语句中返回与type参数相同的类型相关的知识,希望对你有一定的参考价值。

例如:

fun <T> f(a: T): T =
    when (a) {
        a is Int -> 0  // if T is Int, then return Int
        a is String -> ""  // if T is String, then return String
        else -> throw RuntimeException()  // Otherwise, throw an exception so that the return type does not matter.
    }

它给出了编译错误:

Error:(3, 20) The integer literal does not conform to the expected type T
Error:(4, 23) Type mismatch: inferred type is String but T was expected
答案

之后您可以将结果投射到T。您将无法获得任何编译器帮助,您将收到警告,但至少它会编译:

fun <T> f(a: T): T =
    when {
        a is Int -> 0  // if T is Int, then return Int
        a is String -> ""  // if T is String, then return String
        else -> throw RuntimeException()  // Otherwise, throw an exception so that the return type does not matter.
    } as T

请注意,when (a)在这里是不必要的,只需when {即可。

另一答案

目前,当Kotlin编译器分析函数时,它不假设身体各部分的类型参数的某些特定情况。

相反,使用类型参数T的代码应该对任何T都是正确的。返回Int预期T不被认为是安全的,因为它的分析不够深,无法证明如果函数到达那个分支,T总是Int的超类型。

一个选项只是对T进行未经检查的转换,就像在@nhaarman的回答中一样,表示你确定类型是正确的。

另一种解决方案是使用不同类型的函数进行多次重载:

fun f(a: Int) = 1
fun f(a: String) = ""
fun f(a: Any): Nothing = throw RuntimeException()

在这种情况下,编译器将根据您传递的参数选择函数重载,而不是将单个泛型函数专门化为某个类型参数,这对于编译器来说是一个更简单的任务,因为它不涉及任何类型分析在函数体内。


另外,类似的问题:

以上是关于是否可以在when语句中返回与type参数相同的类型的主要内容,如果未能解决你的问题,请参考以下文章

SQL语句中case,when,then的用法

$.when 是不是以与数组中相同的顺序解析延迟数组?

是否可以让“type”的输出返回不同的类?

MySQL 的CASE WHEN 语句

励志当一名性工作者————杂记

Python赋值与深浅拷贝