Kotlin 内联值类 - 无法重写 hashCode() 函数

use*_*472 6 hashcode kotlin value-class

我只是无法重写值类上的 hashCode() 函数。最小的例子(我知道在这个例子中不需要覆盖它......)

@JvmInline
value class Identifier(val value: String){
    override fun hashCode(): Int = this.value.hashCode()
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:名称为“hashCode”的成员已保留用于未来版本

编辑:有什么方法可以指定自己的 hashCode() 函数吗?

Swe*_*per 14

截至目前,您无法重写值类的equalsorhashCode方法。语言规范明确不允许这样做:

值类别必须遵守以下限制:

  • [...]
  • 它们不得覆盖equals以下hashCode成员函数kotlin.Any
  • [...]

这是因为 Kotlin 的开发人员计划添加一个equals您可以重写的强类型方法。

来自内联类提案

Any( toString, hashCode, )中的方法equals对于用户定义的内联类很有用,因此应该是可定制的。方法toStringhashCode可以像通常的方法一样被重写Any。对于方法,equals我们将引入表示“类型化”的新运算符equals,以避免内联类装箱:

@JvmInline
value class Identifier(val value: String){
    override fun hashCode(): Int = ...

    operator fun equals(other: Identifier): Boolean = ...
}
Run Code Online (Sandbox Code Playgroud)

这样,当您==在带有自定义的值类上使用时equals,您不必每次将其传递给方法Any?上的参数时都将它们装箱Any.equals。编译器还会equals(Any?)根据您的equals(Identifier)实现自动生成一个实现。

但他们还没有实现这个功能。这就是为什么他们不让你实现hashCode- 因为如果你这样做,你很可能还需要实现equals(Any?)(仅仅实现很少有用/正确hashCode),但这意味着你的代码将在未来版本的 Kotlin 中崩溃!在未来的版本中,您需要实现equals(Identifier),而不是equals(Any?).

所以只能等到这个功能上线了。在那之前,您不能拥有hashCode并且equals不会委托给包装的值。