【问题标题】:Companion objects hide class -- bug or feature?伴随对象隐藏类——错误或功能?
【发布时间】: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


【解决方案1】:

根据documentation,解决方案是省略名称:

companion object {
    fun someHelper() {}
}

这将创建一个伴生对象,而不会与类名冲突(正如显式命名的伴生对象Foo 所做的那样)。它的方法仍然可以作为Foo.someHelper() 使用,Foo.Companion.someHelper() 的简写。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 2014-10-24
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    相关资源
    最近更新 更多