Изменить локальные переменные внутри Kotlin Lambdas - PullRequest
0 голосов
/ 02 марта 2020

Из того, что я уже знаю: когда вызов функции завершает все локальные переменные внутри нее уничтожаются.

Вопрос : как в приведенном ниже фрагменте кода лямбда может изменить значение локальной переменной (цветовой переменной)? Лямбда запускается, когда в RadioGroup происходит событие, и когда это происходит, функция showDialog() доходит до конца.

fun init() {
  var color = 0
  rg.setOnCheckedChangeListener { group, checkedId ->
    val childCount = group.childCount
    for (index in 0 until childCount) {
      val button = group.getChildAt(index)
      if (button.id == checkedId) {
        color = index
      }
    }
  }
}

Ответы [ 2 ]

3 голосов
/ 02 марта 2020

В Android Studio вы можете использовать Инструменты -> Kotlin -> Показать Kotlin Байт-код, а затем Декомпилировать, чтобы увидеть, как может выглядеть соответствующий код Java.

Вы будете затем посмотрите, что color фактически превращается в final IntRef color = new IntRef();, где IntRef - это класс во время выполнения Kotlin, в котором есть член publi c int element, содержащий фактическое значение.

color - это final ссылка на объект, ваш OnCheckedChangeListener может захватить его просто отлично. Однако член int не является final, поэтому вы можете назначить его (компилятор превращает ваш color = index в color.element = index;).

0 голосов
/ 02 марта 2020

Это внутренне заменено ссылкой на один элемент массива.

Подумайте об этом так:

fun init() {
  var color = arrayOf()
  color[0] = 0
  rg.setOnCheckedChangeListener { group, checkedId ->
    val childCount = group.childCount
    for (index in 0 until childCount) {
      val button = group.getChildAt(index)
      if (button.id == checkedId) {
        color[0] = index
      }
    }
  }
}

Вот так можно получить доступ после факта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...