Может кто-нибудь объяснить это выражение Kotlin? - PullRequest
1 голос
/ 05 октября 2019

Я изучаю разработку Android с использованием Kotlin. Будучи в первую очередь веб-разработчиком, я новичок в обеих технологиях.

В поисках решения API-29 Connectivity Solution (NetworkInfo и getActiveNetworkInfo устарели в API-29), я наткнулся на это выражение для переменнойдекларация.

 protected var callbackFunction: ((Boolean) -> Unit) = {}

 abstract fun startListening(callback: (Boolean) -> Unit)

Как бы я это истолковал? Должен ли я сказать, переменная callbackFunction имеет тип Boolean, или типа Unit . Или что-то другое. Является ли в этой абстрактной функции тип обратного вызова логическим или единичным или что-то еще?

Также я немного запутался насчет фигурных скобок. Означает ли это, что переменная инициализируется пустой анонимной функцией (что-то вроде JavaScript) или это совершенно другое понятие?

1 Ответ

5 голосов
/ 05 октября 2019

Kotlin поддерживает функциональное программирование, что означает, что функции рассматриваются как граждане первого класса в Kotlin. Они могут передаваться или возвращаться из функций, как и любая другая переменная.

Итак,

 protected var callbackFunction: ((Boolean) -> Unit) = {}

callbackFunction - это переменная, которая реализует функцию interface. Вы можете эффективно сказать, что это лямбда. Чтобы определить лямбда тип , после : он принимает Boolean в качестве параметра, а после стрелки -> означает, что он возвращает Unit, что void в терминах Java. После = мы даем ему тело с фигурными скобками.

Вот как это будет выглядеть при вызове:

 class Test {
    var callbackFunction: ((Boolean) -> Unit) = {}
    fun higherOrderFunction(block: (Boolean) -> Unit) {
         block(true)
     }
   }

   fun main() {
      Test().higherOrderFunction { it ->
          println(it) //print true
      }  
   }

Если мы посмотрим на байт-код, мы можемпосмотрите, что он делает под капотом:

Декомпилированный Тестовый класс

  public final class Test {
  @NotNull
   private Function1 callbackFunction;  

  @NotNull
  public final Function1 getCallbackFunction() {
    return this.callbackFunction;
  }

   public final void setCallbackFunction(@NotNull Function1 var1) {
    Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
    this.callbackFunction = var1;
  }

   public Test() {
     this.callbackFunction = (Function1)null.INSTANCE;
   }
 }

Проверьте, как callbackFunction имеет тип Function1. Теперь давайте посмотрим объявление Function1.

/** A function that takes 1 argument. */
public interface Function1<in P1, out R> : Function<R> {
  /** Invokes the function with the specified argument. */
  public operator fun invoke(p1: P1): R
}

Вы можете передать переменную callbackFunction абстрактному методу startListening(), так как этот метод принимает лямбду, которая принимает логическое значение в качестве параметра и возвращает Unit. Итак, callbackFunction соответствует параметру абстрактного метода, и теперь мы можем его передать.

Как бы я это интерпретировал?

  • Можно сказать, что, «callbackFunction - это лямбда, которая принимает логическое значение в качестве аргумента и ничего не возвращает».

В этой абстрактной функции тип обратного вызова является логическим или единичным или чем-то еще?

  • Он принимает лямбду, которая (снова), требует логическое значение в качестве аргумента и ничего не возвращает.

о фигурных скобках. Означает ли это, что переменная инициализируется пустой анонимной функцией?

  • Так же, как мы можем поставить фигурные скобки для объявления abstract, чтобы дать ему конкретную реализацию, мы можем сделать то же самое здесь.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...