具有委托属性的类的toString重写限制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有委托属性的类的toString重写限制相关的知识,希望对你有一定的参考价值。
我是Kotlin的新手,我正在尝试自定义委托属性的文档中的示例。
https://try.kotlinlang.org/#/Examples/Delegated%20properties/Custom%20delegate/Custom%20delegate.kt
通常在重写toString方法时,我会像所提供的代码一样限制要打印的字段。
在这种情况下,p是延迟的属性,我们在getValue()字符串中使用thisref。因此,这里由于递归调用而产生了堆栈溢出的问题。
class Example {
var p: String by Delegate()
var q: String = "testQ"
override fun toString() = "Example[p=$p]"
}
class Delegate() {
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String {
return "$thisRef, thank you for delegating '${prop.name}' to me!"
}
operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {
println("$value has been assigned to ${prop.name} in $thisRef")
}
}
由于委托属性是针对公共库的,因此应该遵循toString()重写方法的任何限制。
答案
问题不是委托,而是递归:
- Example.toString()被称为
- Delegate.getValue()由
$p
调用。 Example的一个实例传递给getValue。 - Example.toString()由
$thisRef
调用。因此它循环回到步骤1!
您可以通过这个非常简单的示例重现该内容:
fun main() {
class SimpleExample {
override fun toString() = "$this"
}
println(SimpleExample())
}
为了修复它,从$thisRef
功能中删除getValue
。
另一答案
return "$thisRef ... "
在上面您想调用thisRef.toString()
(在字符串模板中toString
被隐式调用)。然后尝试执行以下行:"Example[p=$p]"
。因此,它尝试再次调用thisRef.toString()
,而我们再次处于"Example[p=$p]"
调用中。
它会说这完全是预期的行为。那你能做什么?不要在委托中使用$thisRef
;)
以上是关于具有委托属性的类的toString重写限制的主要内容,如果未能解决你的问题,请参考以下文章