如何在Kotlin中定义静态扩展方法?这甚至可能吗?我目前有一个扩展方法,如下所示。
public fun Uber.doMagic(context: Context) {
// ...
}
可以在实例上调用上述扩展名。
uberInstance.doMagic(context) // Instance method
但我如何制作如下所示的静态方法。
Uber.doMagic(context) // Static or class method
答案 0 :(得分:105)
要实现Uber.doMagic(context)
,您可以编写Uber
的{{3}}扩展名(需要配套对象声明):
class Uber {
companion object {}
}
fun Uber.Companion.doMagic(context: Context) { }
答案 1 :(得分:9)
这是官方文件所说的:
Kotlin为包级函数生成静态方法。科特林 也可以为named中定义的函数生成静态方法 对象或伴随对象,如果您将这些函数注释为 @JvmStatic。例如:
class C {
companion object {
@JvmStatic fun foo() {}
fun bar() {}
}
}
现在,foo()在Java中是静态的,而bar()不是:
C.foo(); // works fine
C.bar(); // error: not a static method
答案 2 :(得分:5)
您可以使用Companion对象创建静态方法,如:
class Foo {
// ...
companion object {
public fun bar() {
// do anything
}
}
}
然后你可以这样称呼它:
class Baz {
// ...
private fun callBar() {
Foo.bar()
}
}
答案 3 :(得分:1)
由于我在搜索时不断遇到这种情况,因此这是另一种方法,我还没有看到有人提到它以静态方式起作用,而 可以与泛型一起使用!
扩展定义:
// Extension function
fun <T> KClass<T>.doSomething() = /* do something */
// Extension Property
val <T> KClass<T>.someVal get() = /* something */
用法:
MyType::class.doSomething()
MyType::class.someVal
如您所见,诀窍是将扩展功能附加到类型的KClass
上,因为可以静态引用该扩展功能。
答案 4 :(得分:0)
建议您查看this链接。正如您在那里看到的那样,您应该在包(文件)的顶层声明方法:
package strings
public fun joinToString(...): String { ... }
这等于
package strings;
public class JoinKt {
public static String joinToString(...) { ... }
}
使用constans一切都是一样的。这个声明
val UNIX_LINE_SEPARATOR = "\n"
等于
public static final String UNIX_LINE_SEPARATOR = "\n";
答案 5 :(得分:0)
我实际上是在30分钟前提出了这个确切的问题,所以我开始四处搜寻,但找不到任何解决方案或解决方法,但是在Kotlinglang网站上搜索this section时发现:>
请注意,可以使用可为空的接收器类型定义扩展。即使对象变量的值为null,也可以对其进行扩展。
所以我有一个最疯狂的想法,为什么不定义一个带有可为空的接收器的扩展函数(实际上不使用该接收器),然后在一个空对象上调用它呢! 所以我尝试了一下,效果很好,但是看起来很丑。就像这样:
(null as Type?).staticFunction(param1, param2)
因此,我在接收器类型的扩展文件中创建一个值为NULL的val,然后在其他类中使用它来解决此问题。
因此,作为示例,这是我如何为Android中的Navigation
类实现“静态”扩展功能:
在我的NavigationExtensions.kt文件中:
val SNavigation: Navigation? = null
fun Navigation?.createNavigateOnClickListener(@IdRes resId: Int, args: Bundle? = null, navOptions: NavOptions? = null,
navigationExtras: Navigator.Extras? = null) : (View) -> Unit {
//This is just implementation details, don't worry too much about them, just focus on the Navigation? part in the method declaration
return { view: View -> view.navigate(resId, args, navOptions, navigationExtras) }
}
在使用它的代码中:
SNavigation.createNavigateOnClickListener(R.id.action_gameWonFragment_to_gameFragment)
很明显,这不是一个类名,它只是具有空值的类类型的变量。在扩展制造商方面(因为他们必须创建变量)和开发人员方面(因为他们必须使用SType
格式而不是实际的类名)这显然很丑陋,但这是最接近的与实际的静态功能相比,现在可以实现。希望Kotlin语言制作者将对所创建的issue做出回应,并在该语言中添加该功能。
答案 6 :(得分:0)
要在kotlin中创建扩展方法,您必须创建一个kotlin文件(不是类),然后在该文件中声明您的方法 例如:
public fun String.toLowercase(){
// **this** is the string object
}
将功能导入您正在使用的类或文件中并使用它。
答案 7 :(得分:0)
我还需要具有使用静态方法扩展Java对象的能力,发现对我来说最好的解决方案是创建一个扩展Java类并在其中添加我的方法的Kotlin对象。
object Colour: Color(){
fun parseColor(r: Int?, g: Int?, b: Int?) = parseColor(String.format("#%02x%02x%02x", r, g, b))
}
调用:
val colour = Colour.parseColor(62, 0, 100)
答案 8 :(得分:-2)
我也非常喜欢在Kotlin中添加静态扩展方法。作为现在的解决方法,我将exntension方法添加到多个类中,而不是在所有类中使用一个静态扩展方法。
class Util
fun Util.isDeviceOnline(context: Context): Boolean {
val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = connMgr.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
fun Activity.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
fun OkHttpClient.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }