Kotlin成员和扩展在同一时间

为了了解更多关于Kotlin的信息,我正在开发一个示例Android应用程序,我可以尝试不同的东西。

然而,即使经过了一段时间的研究,我还是无法为以下问题找到合适的答案:

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

fun View.isViewVisibility(v: Int): Boolean = visibility == v 

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

 val f: (Int) -> Boolean = View::isViewVisibility 

目前给我:

错误:(57,35)类型不匹配:推断的类型是KFunction2,但(Int) – >布尔预期错误:(57,41)'isViewVisibility'同时是一个成员和一个扩展。 对这些元素的引用是不允许的

有没有解决办法? 谢谢 !

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

 val f: (View, Int) -> Boolean = View::isViewVisibility 

作为一种解决方法,您可以创建一个单独的普通函数,并从内联扩展方法调用它:

 inline fun View.isVisibility(v: Int): Boolean = isViewVisibility(this, v) fun isViewVisibility(v: View, k: Int): Boolean = (v.visibility == k) 

您不能直接调用扩展方法,因为您没有可用的隐式对象。

更合适的是扩展函数类型View.(Int) -> Boolean

 val f: View.(Int) -> Boolean = View::isViewVisibility 

但实际上,扩展类型大多可以与普通函数类型互换( 赋值兼容 ),接收器是第一个参数:

View.(Int) -> Boolean (View, Int) -> Boolean

使用带有两个参数的类型(第一个用于隐式接收者,就像@Bakawaii已经提到过的那样)或者扩展类型都可以在没有任何警告的情况下工作。

我们以这个函数为例:

 fun String.foo(f: Int) = true 

您可以使用将其分配给具有两个参数函数类型的属性,如下所示:

 val prop: (String, Int) -> Boolean = String::foo fun bar() { prop("bar", 123) } 

或者,您可以使用扩展函数类型,然后使用以下两种语法之一进行调用:

 val prop2: String.(Int) -> Boolean = String::foo fun bar2() { prop2("bar2", 123) "bar2".prop2(123) } 

再次,上述应该都运行没有任何错误或警告。