简体   繁体   English

如何在 kotlin 中修改其 scope 之外的变量?

[英]How to modify variables outside of their scope in kotlin?

I understand that in Kotlin there is no such thing as "Non-local variables" or "Global Variables" I am looking for a way to modify variables in another "Scope" in Kotlin by using the function below:我了解在 Kotlin 中没有“非局部变量”或“全局变量”之类的东西我正在寻找一种方法来修改 Kotlin 中另一个“范围”中的变量,方法是使用下面的 ZC1C425268E68385D1ABZA944F:

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

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

the value of listsize is always 0 (logging the result from inside of the .addOnSuccessListener scope returns 8) so clearly the listsize variable isn't being modified. listsize 的值始终为 0(从.addOnSuccessListener scope 内部记录结果返回 8)所以很明显listsize变量没有被修改。 I have seen many different posts about this topic on other sites, but none fit my usecase.我在其他网站上看到了很多关于这个主题的不同帖子,但没有一个适合我的用例。

I simply want to modify listsize inside of the .addOnSuccessListener callback我只是想在.addOnSuccessListener回调中修改listsize

This method will always be returned 0 as the addOnSuccessListener() listener will be invoked after the method execution completed.此方法将始终返回 0,因为在方法执行完成后将调用addOnSuccessListener()侦听器。 The addOnSuccessListener() is a callback method for asynchronous operation and you will get the value if it gives success only. addOnSuccessListener()asynchronous操作的回调方法,如果它只成功,您将获得该值。

You can get the value by changing the code as below:您可以通过更改以下代码来获取值:

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
 }
}

What you're looking for is a way to bridge some asynchronous processing into a synchronous context.您正在寻找的是一种将一些异步处理桥接到同步上下文的方法。 If possible it's usually better (in my opinion) to stick to one model (sync or async) throughout your code base.如果可能的话,(在我看来)在整个代码库中坚持使用一个 model(同步或异步)通常会更好。

That being said, sometimes these circumstances are out of our control.话虽如此,有时这些情况是我们无法控制的。 One approach I've used in similar situations involves introducing a BlockingQueue as a data pipe to transfer data from the async context to the sync context.我在类似情况下使用的一种方法是引入BlockingQueue作为数据 pipe 以将数据从异步上下文传输到同步上下文。 In your case, that might look something like this:在您的情况下,这可能看起来像这样:

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()
  }
}

The key points are:关键点是:

  • there is a blocking variant of the Queue interface that will be used to pipe data from the async context (listener) into the sync context (calling code) Queue接口有一个阻塞变体,将用于 pipe 数据从异步上下文(侦听器)到同步上下文(调用代码)
  • data is put() on the queue within the OnSuccessListener数据put() OnSuccessListener内的队列中
  • the calling code invokes the queue's take() method, which will cause that thread to block until a value is available调用代码调用队列的take()方法,这将导致该线程阻塞,直到一个值可用

If that doesn't work for you, hopefully it will at least inspire some new thoughts!如果这对你不起作用,希望它至少能激发一些新的想法!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM