Kotlin,向具有另一种接收器类型的类添加扩展函数

问题描述 投票:0回答:1

我一直想实现一个 Kotlin 技巧,但我不确定它是否可行。

我们可以向类添加扩展函数,但具有另一种接收器类型吗?

举个例子,假设我们要向抽象类

launchInViewModelScope()
添加一个函数
ViewModel
。但我们希望这个函数只能由
Flow<*>
调用。

ViewModel
Flow
是 kotlin 的一部分,所以我们必须使用扩展函数。

在类体内添加扩展函数时,这种行为是可能的,但这里我们不能在

ViewModel
体内添加函数。

我正在寻找一个解决方案来写这样的东西:

ViewModel.Flow<*>.launchInViewModelScope() { /* doWork */} 
  • 当然,我不想创建
    ViewModel
    的子类,那太简单了:D.
  • 我也不想向 ViewModel 添加伴随对象,因为我需要访问
    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()
    }
}
kotlin generics kotlin-flow
1个回答
0
投票

上下文接收器是您需要的功能。通过

-Xcontext-receivers
编译器选项来启用此实验性功能。然后你可以写:

context(A)
fun B.doSomeThingElse() {
    println("somethingElse")
}

您可以访问函数体中的

A
实例,就好像它是扩展接收器一样。如果您需要明确提及它,您可以说
this@A

© www.soinside.com 2019 - 2024. All rights reserved.