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
实际上接受两个参数View
和Int
。 所以,它的正确类型应该是(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) }
再次,上述应该都运行没有任何错误或警告。