Шаг 101.
Основы Kotlin.
Стандартные функции. Функция run

    На этом шаге мы рассмотрим назначение и применение этой функции.

    Следующая стандартная функция в списке - это run. Функция run похожа на apply, точно так же ограничивая относительную область видимости, но не возвращает объект-приемник.

    Например, вот как можно проверить наличие конкретной строки в файле:

  val menuFile = File("menu-file.txt") 
  val servesDragonsBreath = menuFile.run { 
      readText().contains("Dragon's Breath")
  }

    Функция readText() неявно вызывается относительно объекта-приемника - экземпляра File - подобно функциям setReadable(), setWritable() и setExecutable() в примере с apply. Но в отличие от apply, run возвращает результат лямбды - в нашем случае истину или ложь.

    Функция run может также использоваться для выполнения ссылки на функцию относительно объекта-приемника. Мы уже использовали ссылки на функции (смотри 57 шаг): вот пример, как сделать это с run:

  fun nameIsLong(name: String) = name.length >= 20 
  
  "Madrigal".run(::nameIsLong) // Ложь
  "Polarcubis, Supreme Master of NyetHack".run(::nameIsLong) // Истина

    Конечно, вторую строку в этом примере можно заменить прямым вызовом nameIsLong("Madrigal"), однако выгоды от использования run становятся более очевидными, когда требуется вызвать несколько функций: вызов цепочкой с помощью run проще читать и анализировать. Например, взгляните на следующий код, который проверяет длину имени игрока, формирует сообщение в зависимости от результата и выводит его.

  fun nameIsLong(name: String) = name.length >= 20 
  fun playerCreateMessage(nameTooLong: Boolean): String { 
      return if (nameTooLong) {
      "Name is too long. Please choose another name." 
      } else {
          "Welcome, adventurer"
      }
  }

  "Polarcubis, Supreme Master of NyetHack"
    .run(::nameIsLong)
    .run(::playerCreateMessage)
    .run(::println)

    Сравните цепочку вызовов в run с тремя вложенными вызовами функций:

  println(playerCreateMessage(nameIsLong("Polarcubis, Supreme Master of NyetHack")))

    Вложенные вызовы функций сложнее понять, потому что читатель должен читать код справа налево, а не слева направо, как мы привыкли.

    Обратите внимание, что есть другая форма вызова run, без объекта-приемника. Эта форма встречается гораздо реже, но мы включим ее сюда для полноты описания:

  val status = run {
    if (healthPoints == 100) "perfect health" else "has injuries"
  }

    На следующем шаге мы рассмотрим функцию with.




Предыдущий шаг Содержание Следующий шаг