假设我有以下函数定义。
fun<T> parse(a: Any): T = when (a) {
is String -> a
else -> false
}
我猜这应该是有效的。但是,IntelliJ IDEA linter显示类型不匹配错误
话虽如此,我会将我的解析函数的返回类型更改为Any,对吧?那么,在Kotlin中使用Any类型和Generics有什么区别?在哪些情况下应该使用这些?
我确实阅读了以下question,但由于我很新的事实,我对Kotlin中的明星投影一无所知。
答案 0 :(得分:3)
您定义为T
的返回类型,但没有任何信息可以确保T
和a: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
}
答案 1 :(得分:1)
您的示例不使用T
,因此无论如何都要将其设为通用。
想一想:作为客户,你将某些东西放入一个函数中,例如一个XML - ByteArray
,该函数应该解析为Object
。调用你不希望它返回的函数Any
(Casting糟透了)但希望函数返回解析对象的类型。这可以通过泛型来实现:
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())
查看方法调用:您告诉泛型预期返回什么类型。代码没有用,只能让你了解泛型。
答案 2 :(得分:1)
我猜这应该是有效的
为什么会这样?您在一个分支中返回String
,在另一个分支中返回Boolean
。因此,整个when
表达式的通用类型是Any
,而编译器(和IDEA)所说的是&#34;找到&#34;。您的代码还说它应该是T
(这是&#34;必需&#34;)。
您的通用方法适用于任何T
,例如对于Int
,但Any
不是Int
的子类型,因此代码无效。
那么,在Kotlin中使用Any类型和Generics有什么区别?
这就像询问&#34;使用数字和文件之间有什么区别&#34;:它们首先没有多少共同之处。您使用泛型来编写可以使用所有类型T
的代码(或者满足某些约束的所有类型);如果需要特定类型Any
,请使用Any
。