Тип этой внутренней сопрограммы

У меня есть функция:

fun buttonClick(view: View){
    CoroutineScope(Dispatchers.Default).launch{ //this:CoroutineScope 
    Log.i(TAG,"${this.javaClass.toString()}")
    while (this.isActive) {
    //...
                }
         }
    }

В Logcat я вижу: class kotlinx.coroutines.StandaloneCoroutine. Но если я захожу внутрь while (this.isActive) во время отладки, я вижу вызов CoroutineScope.isActive, а не вызов метода StandaloneCoroutine (или AbstractCoroutine). то есть это тип CoroutineScope, а не StandaloneCoroutine. Может ли кто-нибудь объяснить такое поведение?


person Kubick    schedule 29.03.2021    source источник


Ответы (2)


Когда вы проверяете свой код в среде IDE, this известен как CoroutineScope только в контексте кода вокруг него. Компилятор знает только this как CoroutineScope, потому что это тип, определенный в launch(). Фактический экземпляр CoroutineScope в этом случае оказывается экземпляром StandaloneCoroutine, который реализует интерфейс CoroutineScope. StandaloneCoroutine - это частная деталь реализации, которую вы можете проверять только во время выполнения, используя отражение (как вы это делали, используя javaclass).

person Tenfour04    schedule 29.03.2021

StandaloneCoroutine является подтипом всех этих: Job, JobSupport, Continuation и CoroutineScope.

С другой стороны, isActive - это свойство расширения на CoroutineScope. Свойства / функции расширения не относятся к типам, что является их фундаментальной характеристикой. Не имеет значения, какая у вас реализация CoroutineScope, реализация свойства extension всегда единственная и неповторимая public val CoroutineScope.isActive: Boolean, и IDE перенесла вас туда.

Возможно, вы были сбиты с толку тем фактом, что это свойство расширения объявлено в файле CoroutineScope.kt, но если вы внимательно посмотрите, вы увидите, что это объявление верхнего уровня, а не внутри интерфейса CoroutineScope (который является всего лишь однозначным). лайнер).

person Marko Topolnik    schedule 29.03.2021