如何实现范围内所有内容均可访问的属性

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

我想知道在 Kotlin 中是否可以创建一个“上下文”,对象可以从中获取数据。类似于以下内容:

MyScope(myGlobalObject) {
    val objectA = MyClassA()
    objectA.doSomething()
}

ClassA() {
   fun doSomething() {
       val resultA = ...
       myGlobalObject.add(resultA)
       val objectB = ClassB()
       objectB.doSomethingElse()
   }
}

ClassB() {
   fun doSomethingElse() {
      val resultB = ...
      myGlobalObject.add(resultB)
   }
}

我不希望 MyScope 成为单例,因为这是多线程环境(服务器请求),我不希望其他线程弄乱 MyScope 本地实例中的上下文

上面的代码本着避免传递

myGlobalObject
几个级别的精神,如下:

val objectA = MyClassA(myGlobalObject)
objectA.doSomething()

ClassA constructor(val myGlobalObject) {
   fun doSomething() {
       val resultA = ...
       myGlobalObject.add(resultA)
       val objectB = ClassB(myGlobalObject)
       objectB.doSomethingElse()
   }
}

ClassB constructor(val myGlobalObject) {
   fun doSomethingElse() {
      val resultB = ...
      myGlobalObject.add(resultB)
   }
}

换句话说,类似于其他框架,例如 React 和 ReactContexts。一直在互联网上搜索,似乎有可能,JetPack compose有这种感觉,但不确定是否可以像上面那样传递数据,或者是否有办法从代码的任何部分“到达”范围。 ..我知道它可能返回 null 或未初始化,但这是我完全可以接受的

kotlin jvm
1个回答
0
投票

我相信您正在寻找Context Receivers的实验性功能。您可以通过传递

-Xcontext-receivers
编译器选项来启用此功能。

假设您希望您的函数访问这样的对象:

// as per your requirements, not a singleton
class SomeGlobalObject {
    fun foo() {
        println("foo")
    }
    fun bar() {
        println("bar")
    }
}

您可以在函数声明前加上

context(SomeGlobalObject)
:

context(SomeGlobalObject)
fun thisNeedsAGlobalObject() {
    // here you can use members of SomeGlobalObject without qualification
    foo()
    bar()

    // if there is ambiguity, you can qualify it with 'this@SomeGlobalObject'
    [email protected]()
}

需要

SomeGlobalObject
的函数可以调用其他需要
SomeGlobalObject
的函数:

context(SomeGlobalObject)
fun somethingElseThatNeedsAGlobalObject() {
    thisNeedsAGlobalObject()
}

您可以使用

with
启动存在
SomeGlobalObject
的范围:

fun main() {
    with(SomeGlobalObject()) {
        thisNeedsAGlobalObject()
    }
}

您还可以使函数需要多个不同类型的上下文接收器。请参阅 KEEP 提案了解更多功能。

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