gpt4 book ai didi

reflection - 如何获取 Kotlin 属性的名称?

转载 作者:IT老高 更新时间:2023-10-28 13:45:27 26 4
gpt4 key购买 nike

我有以下函数来访问属性的委托(delegate)。它使用 Kotlin 反射获取属性名称,使用 Java 反射获取字段。

fun Any.getDelegate<T>(prop: KProperty<T>): Any {
return javaClass.getDeclaredField("${prop.name}\$delegate").let {
it.setAccessible(true)
it.get(this)
}
}

方法是这样使用的:

val delegate = a.getDelegate(A::b)

但是,我更喜欢这样使用它:

val delegate = a.b.delegate

上面代码的问题是获取a.b的属性名,并从a.b获取实例a。根据我对 Kotlin 的了解,这可能是不可能的,但是我想看看我是否可以清理我的函数。

为了更全面地了解我正在尝试做的事情,这是我的完整代码。我想要一个可观察的委托(delegate),我可以使用委托(delegate)引用添加和删除观察者,而无需创建附加变量。

fun Any.addObservable<T>(prop: KProperty<T>, observer: (T) -> Unit) {
getObservableProperty(prop).observers.add(observer)
}

fun Any.getObservableProperty<T>(prop: KProperty<T>): ObservableProperty<T> {
return getDelegate(prop) as ObservableProperty<T>
}

fun Any.getDelegate<T>(prop: KProperty<T>): Any {
return javaClass.getDeclaredField("${prop.name}\$delegate").let {
it.setAccessible(true)
it.get(this)
}
}

class ObservableProperty<T>(
initialValue: T,
initialObservers: Array<(T) -> Unit> = emptyArray()) : ReadWriteProperty<Any?, T> {

private var value = initialValue

public val observers: MutableSet<(T) -> Unit> = initialObservers.toHashSet()

public override fun get(thisRef: Any?, desc: PropertyMetadata): T {
return value
}

public override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) {
this.value = value
observers.forEach { it(value) }
}
}

class A() {
var b by ObservableProperty(0)
}

fun main(args: Array<String>) {
val a = A()

a.addObservable(A::b) {
println("b is now $it")
}

a.b = 1
a.b = 2
a.b = 3
}

编辑:

我刚刚意识到该函数也不严格,因为属性委托(delegate)字段名称由 KProperty 名称引用,这不需要对封闭类的强引用。这是一个演示问题的示例:

class A() {
var foo by ObservableProperty(0)
}

class B() {
var foo by ObservableProperty(0)
}

fun main(args: Array<String>) {
val a = A()

a.addObservable(B::foo) {
println("b is now $it")
}

a.foo = 1
a.foo = 2
a.foo = 3
}

这编译并运行没有错误,因为 A::fooB::foo 都产生 "foo$delegate 的字段字符串>.

最佳答案

现在,我们可以通过反射来获取委托(delegate)对象。我们正在设计一种语言功能来直接访问委托(delegate)实例,但这还有很长的路要走。

关于reflection - 如何获取 Kotlin 属性的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31198230/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com