当 T 是类型 "Any" 时,通用参数需要类型 "Nothing"

Generic Parameter Requires type "Nothing" when T is type "Any"

我是一名新的 Kotlin 程序员,我遇到了与泛型相关的问题

在下面的代码中,我收到 it.get(this)“类型不匹配”的错误。 要求:无。发现:任何。

inline fun <reified T : Any> Any.getPropertiesWithType() =
    this::class.memberProperties
        .filter { it.returnType.isSubtypeOf(T::class.starProjectedType) }
        .map {
            it.isAccessible = true
            it.get(this) as T
        }

这令人困惑,因为 memberProperties returns a Collection<KProperty1<T, *>> 其中 T 是 this 的类型,在我的例子中是 AnyKProperty1.get() 接受一个相同类型 T 的参数,所以我希望 Any 可以顺利通过。

我注意到的一件事是过滤器和映射中的 it 都是类型 KProperty<out Any, *>>memberProperties 没有输出方差。

如果我将 this::class 替换为 this.javaClass.kotlin,它可以正常工作,但这似乎是一个非常糟糕的方法。

如果有人知道解决此问题的方法或完全不同的策略,我们将不胜感激。我是 Kotlin 的新手,有时仍然以 Java 的方式做事。

this::class 类似于 Java 中的 this.getClass(),其中 returns 是 KClass<out Any>(Java 中的 Class<? extends Object>) .毕竟,仅仅因为 this 的类型是 Any,它的运行时类型可能不是 Any——它可能是 Any 的任何子类。 out Any 抓住了这个想法。

因此,this::classmemberProperties将是KProperty1<out Any, *>的集合。

就像您不能使用 addMutableList<out Any> 添加任何内容一样,您不能 get KProperty1<out Any, *> 的值 - 输入参数的类型是标记为 out。另一种思考方式是 属性 可以在 Any 的任何子类上,试图使用 this 获得 属性,这只是一个 Any,显然不行。

我会将未经检查的转换移动到 it:

(it as KProperty1<Any, T>).get(this)

至于为什么.javaClass有效,是因为javaClass实际上给你一个Class<Any>,而不是Class<out Any>。 IMO,这没有多大意义,但事实就是如此。