如何修改科特林范围之外的变量?

How to modify variables outside of their scope in kotlin?

我知道在 Kotlin 中没有“非局部变量”或“全局变量”这样的东西我正在寻找一种方法来使用以下函数在 Kotlin 的另一个“范围”中修改变量:

class Listres(){
var listsize = 0
fun gatherlistresult(){
    

    var listallinfo = FirebaseStorage.getInstance()
                                     .getReference()
                                     .child("MainTimeline/")
                                     .listAll()
    listallinfo.addOnSuccessListener {
        listResult -> listsize += listResult.items.size
    }
                
    
}
}

listsize 的值始终为 0(从 .addOnSuccessListener 范围 returns 8 内部记录结果)很明显 listsize 变量没有被修改。我在其他网站上看到过许多关于此主题的不同帖子,但 none 适合我的用例。

我只是想修改 listsize 内部的 .addOnSuccessListener 回调

此方法将始终返回 0,因为 addOnSuccessListener() 侦听器将在方法执行完成后调用。 addOnSuccessListener()asynchronous操作的回调方法,只有成功才会得到值。

您可以通过更改以下代码来获取该值:

class Demo {

 fun registerListResult() {
     var listallinfo = FirebaseStorage.getInstance()
                                     .getReference()
                                     .child("MainTimeline/")
                                     .listAll()
    listallinfo.addOnSuccessListener {
        listResult -> listsize += listResult.items.size
        processResult(listsize)
    }
    listallinfo.addOnFailureListener {
        // Uh-oh, an error occurred!
     }
 }

 fun processResult(listsize: Int) {
    print(listResult+"") // you will get the 8 here as you said
 }
}

您正在寻找的是一种将一些异步处理桥接到同步上下文中的方法。如果可能的话(在我看来)在整个代码库中坚持一种模型(同步或异步)通常更好。

话虽这么说,但有时这些情况是我们无法控制的。我在类似情况下使用的一种方法涉及引入 BlockingQueue 作为数据管道以将数据从异步上下文传输到同步上下文。在您的情况下,可能看起来像这样:

class Demo {
  var listSize = 0

  fun registerListResult() {
    val listAll = FirebaseStorage.getInstance()
        .getReference()
        .child("MainTimeline/")
        .listAll()

    val dataQueue = ArrayBlockingQueue<Int>(1)

    listAll.addOnSuccessListener { dataQueue.put(it.items.size) }

    listSize = dataQueue.take()
  }
}

重点是:

  • Queue 接口有一个阻塞变体,用于将异步上下文(侦听器)中的数据通过管道传输到同步上下文(调用代码)
  • 数据在 OnSuccessListener
  • 内的队列中 put()
  • 调用代码调用队列的 take() 方法,这将导致该线程阻塞,直到值可用为止

如果这对您不起作用,希望它至少能激发一些新想法!