На этом шаге мы рассмотрим использование расширения.
Расширение 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)
На следующем шаге мы рассмотрим переименование расширения.