Kotlin:经过改进的泛型似乎不适用于散列/等于比较 [英] Kotlin: Reified generics don't seem to work right for hash/equals comparisons

查看:101
本文介绍了Kotlin:经过改进的泛型似乎不适用于散列/等于比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个KClassInt的映射.然后,我有了一个具有通用泛型类型的函数.然后,我希望出现以下情况,以便给我与Boolean::class

I have a map of KClass to Int. I then have a function which has a reified generic type. I'd then expect the following situation, thus, to give me the Int associated with Boolean::class

val kclassToInt = mapOf(Boolean::class to 1, Byte::class to 1, Short::class to 2)

inline fun <reified T> myExpectations() =
        assertEquals(1, kclassToInt.getRaw(T::class), "Why doesn't it work? :'(")

像这样的myExpectations<Boolean>(),在打给我的时候都受到了Why doesn't it work? :'(. Expected <1>, actual <null>.的问候.

I'm greeted with Why doesn't it work? :'(. Expected <1>, actual <null>. from a call to it like this myExpectations<Boolean>().

然后我尝试不使用.java,所以我使用的是Java的Class而不是Kotlin的KClass.

I then tried to use .java off, so I was using Java's Class rather than Kotlin's KClass.

val classToInt = mapOf(Boolean::class.java to 1, Byte::class.java to 1, Short::class.java to 2)

inline fun <reified T : Any> anotherExpectation() =
        assertEquals(1, classToInt.getRaw(T::class.java))

这次我再次被断言错误打招呼:java.lang.AssertionError: Expected <1>, actual <null>.

This time I was again greeted by assertion error: java.lang.AssertionError: Expected <1>, actual <null>.

最后我尝试使用.javaClass而不是.java:

Finally I tried using .javaClass rather than .java:

val javaClassToInt = mapOf(Boolean::class.javaClass to 1, Byte::class.javaClass to 1, Short::class.javaClass to 2)

inline fun <reified T> pleaseWork() =
        assertEquals(1, javaClassToInt.getRaw(T::class.javaClass))

这次真的很奇怪.我对此表示欢迎:java.lang.AssertionError: Expected <1>, actual <2>.这似乎是因为所有.javaClass都引用了KClassImpl.

This time it was really strange. I was greeted with this: java.lang.AssertionError: Expected <1>, actual <2>. This seems to be because all .javaClass refer to KClassImpl.

最后,我诉诸于我不想做的事,请使用.qualifiedName:

Finally I resorted to what I didn't want to do, use .qualifiedName:

val qnToInt = mapOf(Boolean::class.qualifiedName to 1, Byte::class.qualifiedName to 1, Short::class.qualifiedName to 2)

inline fun <reified T> iKnowItWorks() =
        assertEquals(1, qnToInt.getRaw(T::class.qualifiedName))

当然可以使用,这是我在实际用例中使用的:

Which of course works and is what I use in my actual use case: https://github.com/Jire/kotmem/blob/master/src/main/kotlin/org/jire/kotmem/Process.kt

推荐答案

我认为Map中的键类型是基本类型的KClass实例(Java int而不是Integer).函数中的已修正类型是盒装类型(Integer)的KClass实例,如

I believe that the key types in your Map are KClass instances for the primitive types (Java int rather than Integer). The reified type in the function is the KClass instance for the boxed type (Integer), as seen in Are Kotlin's reified types incorrect for primitives on the JVM?

尽管这两个KClass的打印内容相同,但它们并不相等,因此您的查找失败.

Whilst these two KClasss print as the same thing, they are not equal, so your lookup fails.

这篇关于Kotlin:经过改进的泛型似乎不适用于散列/等于比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆