我一直想实现一个 Kotlin 技巧,但我不确定它是否可行。
我们可以向类添加扩展函数,但具有另一种接收器类型吗?
举个例子,假设我们要向抽象类
launchInViewModelScope()
添加一个函数 ViewModel
。但我们希望这个函数只能由 Flow<*>
调用。
ViewModel
和 Flow
是 kotlin 的一部分,所以我们必须使用扩展函数。
在类体内添加扩展函数时,这种行为是可能的,但这里我们不能在
ViewModel
体内添加函数。
我正在寻找一个解决方案来写这样的东西:
ViewModel.Flow<*>.launchInViewModelScope() { /* doWork */}
ViewModel
的子类,那太简单了:D.ViewModelScope
实例。这是同一问题的框架和代码:
/** SUPPOSE A AND B ARE DEFINED IN A LIBRARY **/
abstract class A {
fun B.doSomeThing() {
println("something")
}
}
class B {
}
/*********************************************/
// Is there an existing way to achieve something like this ?
fun A.B.doSomeThingElse() {
println("somethingElse")
}
// That can allow me to do this :
class AImpl: A() {
val b = B()
fun main() {
// This works as expected
b.doSomeThing()
// I want this to work :
b.doSomeThingElse()
}
}
class C {
val b = B()
fun main() {
// I want this NOT to work :
b.doSomeThingElse()
}
}
上下文接收器是您需要的功能。通过
-Xcontext-receivers
编译器选项来启用此实验性功能。然后你可以写:
context(A)
fun B.doSomeThingElse() {
println("somethingElse")
}
您可以访问函数体中的
A
实例,就好像它是扩展接收器一样。如果您需要明确提及它,您可以说this@A
。