Kotlin 数据类中的循环引用可能会产生堆栈溢出错误

poi*_*poi 5 kotlin

我有一个关于 Kotlin 中数据类的问题。
假设我们有两个带有循环引用的类:

data class Foo(
    var bar: Bar? = null
)
Run Code Online (Sandbox Code Playgroud)
data class Bar (
    var foo: Foo? = null
)
Run Code Online (Sandbox Code Playgroud)

和主要功能:

fun main() {
    val f = Foo()
    val b = Bar()
    f.bar = b
    b.foo = f
    f.hashCode()
    b.hashCode()
    //println(f)
    //println(b)
}
Run Code Online (Sandbox Code Playgroud)

Kotlin 自动生成的代码将使 main 函数进入堆栈溢出。你可以在Kotlin Playground试试这个。
这是预期的行为吗?请注意,这是一个基本示例,但这将发生在现实生活中,例如,在 Bar 中,我们可以拥有 List、Set 或 Foo 的泛型集合,而不是对 Foo 的引用。
Kotlin 不应该产生某种编译器错误,或者即使在其他语言中也会发生这种情况?
同样的事情,但在 Java 中

kab*_*nus 3

这可能被认为是一个错误。这里是与 Kotlin 开发人员的通信,讨论了可能是另一个错误的问题,但重要的是:

\n
\n

默认情况下,不会生成特定的 equals 和 hashCode(因此,它们检查对象身份)。

\n

对于 数据 ,hashCode 和 equals 基于属性值。\nI\xe2\x80\x99 会用文字而不是伪代码编写算法步骤:

\n

哈希码:

\n
    \n
  1. 计算当前类中声明为构造函数参数的每个属性的 hashCode
  2. \n
  3. 返回 h1 \xc3\x97 31n\xe2\x88\x921 + h2 \xc3\x97 31n\xe2\x88\x922 + \xe2\x80\xa6 + hn
  4. \n
\n
\n

这就是预期的行为,并且显然会在步骤 1 中破坏您的示例。在您的“真实”世界示例中,使用可能Array.hashCode是解决方案,但似乎在这个人为的示例中(尽管我已经看到了诸如此类的构造, \ 这就是 C/++ 中存在前向声明的原因...)。我会将其提交到https://youtrack.jetbrains.com/issues。他们可能只是告诉您使用对象 ID 将常规类的 hashCode 设置为默认值。

\n

poipoi发现这实际上是几年前报道的,我错过了:https ://youtrack.jetbrains.com/issue/KT-16244

\n

因此具有循环引用的数据类必须提供自己的toStringhashCode。可惜这不是记录在案的行为。

\n