我想打印我班级的属性值.
fun print() {
val cl = this::class
cl.declaredMemberProperties.filter {it.visibility != KVisibility.PRIVATE}.forEach {
println("${it.name} = ${it.get(this)}")
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试构建此代码时,我收到编译器错误:
Error:(34, 40) Kotlin: Out-projected type 'KProperty1<out SomeClass, Any?>' prohibits the use of 'public abstract fun get(receiver: T): R defined in kotlin.reflect.KProperty1'
Run Code Online (Sandbox Code Playgroud)
当我this改为班级名字时,SomeClass一切都很好
fun print() {
val cl = SomeClass::class
cl.declaredMemberProperties.filter {it.visibility != KVisibility.PRIVATE}.forEach {
println("${it.name} = ${it.get(this)}")
}
}
Run Code Online (Sandbox Code Playgroud)
所以问题是,编译器换型的this::class,以KClass<out SomeClass>代替使用KClass<SomeClass>.知道为什么会这样吗?
这种差异的原因在于,当您使用SomeClass::class引用时,它肯定是表示的类令牌SomeClass而不是其可能的派生类之一,因此它KClass<SomeClass>没有类型投影.
但是this::class在函数open或abstract类函数或扩展函数中编写可以返回派生类的类标记,因此,为了确保类型安全,类型为out-projected:KClass<out SomeClass>表示实际类型参数可以是SomeClass或其子类型.
例:
open class A {
fun f() {
println(this::class) // KClass<out A> because it can be KClass<B>
}
}
class B : A()
B().f()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
217 次 |
| 最近记录: |