【发布时间】:2017-03-26 15:35:35
【问题描述】:
在 Kotlin 中,以下似乎是合理的代码:
data class Foo(val bar: String) {
fun combine(other: Foo): Foo {
return Foo(bar + other.bar)
}
companion object Foo {
fun someHelper() {}
}
}
但是,它不能编译:类型Foo 绑定到Foo.Foo 而不是Foo!
这是一个(语言设计或编译器)错误,还是一个特性?如果是后者,在存在伴随对象的情况下实现combine 的惯用方式是什么?
当然,我会考虑一种解决方法:
fun combine(other: my.package.Foo): my.package.Foo {
return Foo(bar + other.bar)
}
但这不太好,是吗?
【问题讨论】:
-
当然,我可以重命名伴生对象。但这会破坏它的大部分目的,不是吗?
-
我不明白为什么它会破坏它的目的。您命名它以及使用与类相同的名称的目标是什么?
-
@JBNizet 如果伴生对象上的方法要以任何合理的方式替换静态方法,伴生对象最好具有相同的名称。例如,就像 Scala 一样。
-
不,这不是它在 Kotlin 中的工作方式。如果你希望伴生对象中的方法是类的静态方法,你应该用
@JvmStatic注解它们。否则,您可以使用 Foo.Companion.someHelper() 在 Java 中访问它们。在 Kotlin 中,您可以只使用 Foo.someHelper()。 -
@JBNizet 出于讨论的目的,我不太关心 Kotlin 编译器如何在 JVM 字节码中表示伴随对象及其方法。关键是,静态方法在 Java 中服务于特定目的,而伴随对象显然在 Kotlin 中服务于相同目的。与母类同名是其中的一部分。考虑到这种确切的行为是通过省略对象名称来实现的(请参阅下面的答案),我认为我的想法与 Kotlin 的设计者一致。
标签: types kotlin shadowing companion-object data-class