如何在Kotlin中实现未知可空性的函数返回类型?
我希望让函数返回Any!类型,从而自行决定是否处理可空性。目前我发现只有调用Java函数才能实现这种类型,例如:
public static Integer getInt(JsonObject json, String key) { return json.get(key).getAsInt(); }
这样我在Kotlin中既可以将其当作可空类型使用:getInt(json, "id") ?: 0,也可以当作非空类型使用:getInt(json, "id")。由于返回类型是Int!,Kotlin编译器不会针对可空性报错。
请问不依赖Java代码的话,在Kotlin中有没有办法创建这类返回类型?
另外,我不想在每次调用函数时都使用!!,也不想在Kotlin中定义两个类似getInt(...)和getIntOrNull(...)的函数。
在Kotlin里,本身并不支持直接显式声明T!(平台类型)——这是Kotlin为兼容Java无空值声明特性引入的特殊类型。不过有几个变通方案能实现类似效果:
借助泛型擦除与抑制警告
可以通过强制类型转换配合警告抑制,让函数的返回值模糊可空性:@Suppress("UNCHECKED_CAST") fun getInt(json: JsonObject, key: String): Int = json.get(key)?.asInt as Int这种写法下,编译器不会强制你处理可空性:你既可以用
?:兜底空值,也可以直接当作非空值使用,和调用Java的Int!效果一致。但要注意,这本质是绕过了Kotlin的空安全检查,如果实际返回null,直接当作非空使用会抛出ClassCastException,和Java里的空指针风险相同。利用
Nothing?的偏门写法(不推荐)
还有一种可读性极差的技巧,利用Nothing?的特性让编译器推断出类似平台类型的返回值:fun getInt(json: JsonObject, key: String): Int = json.get(key)?.asInt ?: throw null as Nothing?这里
throw null as Nothing?永远不会正常执行(抛出的是NullPointerException),但编译器会将返回类型识别为Int!。但这种写法过于晦涩,实际项目中不建议采用。
需要强调的是,这些方案都是绕过Kotlin的空安全机制,和Java平台类型一样存在运行时空指针风险。使用时要么确保数据源的非空性,要么在需要时主动处理空值场景。
内容的提问来源于stack exchange,提问作者Сергей Андриенко

