具有可空类型的Kotlin泛型

时间:2019-07-24 14:46:00

标签: generics kotlin

我想用以下语义创建一个函数:

fun myFunction(input: <String? or String>): <Same type as input>

并在以后的情况下使用它:

val a1: String
val b1: String = myFunction(a1)

val a2: String?
val b2: String? = myFunction(a1)

如何定义这样的功能?

我尝试过类似的事情:

fun <T: String?> myFunction(value: T): T {
    if (value == null) {
        return null
    }
    return value
}

但是我有编译时错误

2 个答案:

答案 0 :(得分:0)

您必须将返回类型指定为可为空:

fun <T: String?> myFunction(value: T): T? {
    if (value == null) {
        return null
    }
    return value
}

这基本上意味着您不需要通用函数,至少对于String类型的final来说不需要。

编辑:为什么它不能像您想要的那样工作?
假设我们遵循您的签名,但是功能不同:

fun <T : String?> myFunction(value: T): T {
    return null
}

您可以这样调用此函数:

myFunction("banana")

该参数不是null,但函数仍返回null
仅使用类型系统,编译器无法确保仅当输入为null时才返回null

也许您想看看Kotlin contracts

答案 1 :(得分:0)

我建议只进行两个重载:

@JvmName("myFunctionNonNull")
fun myFunction(value: String): String {
    ...
}

fun myFunction(value: String?): String? = value?.let(::myFunction)

如果不这样做,我认为您最好的办法就是添加演员表并说服自己自己是安全的:

@Suppress("UNCHECKED_CAST")
fun <T: String?> myFunction(value: T): T {
    if (value == null) {
        return null as T
    }
    return value as T
}