在伴随对象中使用 Companion.foo 有什么区别?



在 Kotlin 中,如果我在伴随对象中有一个以Companion.为前缀 (Companion.foo( 的函数,与伴随对象内的foo相比,它会有什么区别?

我注意到在下面的代码中,Companion.foo将使其对外部作用域不可见,但对同一伴随对象内的函数仍然可见。

您可以在以下位置找到代码片段: https://pl.kotl.in/t6FvM6ni6

fun main() {
A.foo() // compiler complains "unresolved reference"
A.bar()
B.foo()
}
class A {
companion object {
fun Companion.foo() {
println("hello in A")
}
fun bar() {
foo()
}
}
}
class B {
companion object {
fun foo() {
println("hello in B")
}
}
}

还有其他区别吗?除了可见性之外,A.Companion.fooA.foo是一样的吗?这是在伴随对象中封装方法的一种方法吗?


更新 1

在我的实际项目中,我从同伴对象中的另一个inline函数调用inline函数,这就是不能使用访问修饰符的原因。但如果可能的话,我仍然想隐藏foo

class C {
companion object {
inline fun <reified T> Companion.foo() {
println("hello in A")
}
inline fun bar() {
foo<String>()
}
}
}

在您的示例中,定义Companion.foo()是作为成员的扩展。在这种情况下,在与扩展类型相同的类型A.Companion定义扩展。这是没有用的。

下一个示例演示扩展作为具有两个不同类的成员的概念。这个例子没有同伴,因为它对概念没有区别。

class A 
class B {
fun A.foo() {
println("Extension for A, only visible in B")
println("Function has two 'this' references: ${this} and ${this@B}")
}
fun bar() {
val a = A()
a.foo() // this function call is only possible in the context of `B`
}
}
fun main() {
val a = A()
a.foo() // compile error
}

综上所述,示例中的两个foo()函数在内部具有不同的签名。普通函数foo()是伴随对象上没有参数的简单方法。扩展函数Companion.foo()是伴随对象上的方法,但具有用于第二个this引用的额外参数。

若要将方法封装在同伴中,只需将private修饰符放在函数之前。

如果需要内联函数,请使用internal@PublishedApi对公共 API 隐藏该函数。

class C {
companion object {
@PublishedApi
internal inline fun <reified T> foo() {
println("hello in A")
}
inline fun bar() {
foo<String>()
}
}
}

相关内容

  • 没有找到相关文章

最新更新