Kotlin 成员和扩展同时使用

NSi*_*mon 5 kotlin kotlin-extension

为了更多地了解 Kotlin 并尝试使用它,我正在开发一个示例 Android 应用程序,我可以在其中尝试不同的东西。

但是,即使在该主题上搜索了一段时间后,我也无法为以下问题找到正确的答案:

让我们在 View 类上声明一个(虚拟)扩展函数:

fun View.isViewVisibility(v: Int): Boolean = visibility == v
Run Code Online (Sandbox Code Playgroud)

现在我怎样才能从其他地方引用这个函数以便以后调用 invoke() 呢?

val f: (Int) -> Boolean = View::isViewVisibility
Run Code Online (Sandbox Code Playgroud)

目前给我:

错误:(57, 35) 类型不匹配:推断类型为 KFunction2 但 (Int) -> Boolean was expectedError:(57, 41) 'isViewVisibility' 同时是成员和扩展。不允许引用此类元素

有什么解决方法吗?谢谢 !

Bak*_*aii 7

扩展是静态解析的,其中第一个参数接受接收器类型的实例。isViewVisibility实际上接受两个参数,ViewInt。所以,它的正确类型应该是(View, Int) -> Boolean,像这样:

val f: (View, Int) -> Boolean = View::isViewVisibility
Run Code Online (Sandbox Code Playgroud)

  • 抱歉,我知道这是旧的,但为了人们搜索解决方案:事实上,问题是,您的函数不是顶级函数。不能引用定义为其他类的类成员的扩展。不过不知道为什么。只需将您的扩展定义为顶级功能,您应该没问题。 (3认同)

Jon*_* H. 5

错误消息指出:

'isViewVisibility' 同时是一个成员和一个扩展。不允许引用此类元素

也就是说,该方法既是一个扩展函数(这正是您想要的),又是一个成员。您没有显示定义的完整上下文,但它可能看起来像这样:

// MyClass.kt

class MyClass {
  fun String.coolStringExtension() = "Cool $this"

  val bar = String::coolStringExtension
}

fun main() {
    print(MyClass().bar("foo"))
}
Run Code Online (Sandbox Code Playgroud)

科特林游乐场

正如您所看到的,coolStringExtension被定义为 的成员MyClass。这就是错误所指的内容。Kotlin 不允许您引用也是成员的扩展函数,因此会出现错误。

您可以通过在顶层定义扩展函数(而不是作为成员)来解决此问题。例如:

// MyClass.kt

class MyClass {
  val bar = String::coolStringExtension
}

fun String.coolStringExtension() = "Cool $this"

fun main() {
    print(MyClass().bar("foo"))
}
Run Code Online (Sandbox Code Playgroud)

科特林游乐场