Шаг 216.
Основы Kotlin.
Расширения. Объявление файла-расширения

    На этом шаге мы рассмотрим использование расширения.

    Расширение random() отмечено модификатором видимости private:

private fun <T> Iterable<T>.random(): T = this.shuffled().first()

    Модификатор private не позволяет использовать расширение вне файла, где оно объявлено. В данный момент расширение применяется только в Tavern.kt, поэтому ограничение его видимости с помощью модификатора private имеет определенный смысл. Для расширений действуют те же правила, что и для функций: если расширение не используется где-то еще, отметьте его модификатором private.

    Однако расширение random() определено так, что может вызываться для любого экземпляра Iterable. А есть ли еще места в программе, кроме Tavern.kt, где можно было бы применить его? Да, есть.

    Загляните в Player.kt, и вы увидите код выбора случайного города для Player:

.   .   .   .
    private fun selectHometown() = File("data/towns.txt")
            .readText()
            .split("\n")
            .shuffled()
            .first()
}

    Было бы неплохо эту цепочку также заменить расширением random.

    Так как расширение random() будет использовано в нескольких файлах, использовать модификатор private в дальнейшем не нужно, так же как и оставлять его в Tavern.kt. Хорошим местом для расширений, в случае использования их в нескольких файлах, будет свой собственный файл. А еще лучше - свой собственный пакет.

    Щелкните правой кнопкой мыши (Control+click) на пакете com.bignerdranch.nyethack и выберите в контекстном меню пункт New | Package.


Рис.1. Создание нового пакета

    Назовите пакет extensions и добавьте туда файл с именем IterableExt.kt (рисунок 2).


Рис.2. Добавление расширений в пакет и файл

    В соответствии с соглашениями, файлам, содержащим только расширения, присваиваются имена, начинающиеся с имени расширяемого типа и заканчивающиеся -Ext.

    Переместите расширение random() в IterableExt.kt, удалив старый код из Tavern.kt. Удалите ключевое слово private из определения расширения, когда будете переносить его в IterableExt.kt.

package com.bignerdranch.nyethack.extensions

fun <T> Iterable<T>.random(): T = this.shuffled().first()


Рис.3. Добавление расширения random в IterableExt.kt (IterableExt.kt)

    Теперь, когда вы переместили расширение в отдельный файл и сделали его общедоступным, его можно использовать в Tavern.kt и Player.kt. Но как вы могли заметить, в Tavern.kt появилось сообщение об ошибке. Когда расширение определяется в отдельном файле, его необходимо импортировать в каждый файл, где оно будет использоваться. Добавьте следующую инструкцию импорта расширения random() в начало файла Tavern.ktи Player.kt:

import com.bignerdranch.nyethack.extensions.random

    Теперь измените функцию selectHometown() внутри Player.kt, заменив прежний код выбора случайного города вызовом функции-расширения random().

.   .   .   .
    private fun selectHometown() = File("data/towns.txt")
            .readText()
            .split("\n")
            .random()
}
Файл с проектом можно взять здесь.


Рис.6. Использование random() в selectHometown() (Player.kt)

    На следующем шаге мы рассмотрим переименование расширения.




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