Шаг 201.
Основы Kotlin.
Обобщения. Обобщенные функции

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

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

    Настало время это исправить. Добавьте функцию, которая позволяет игроку достать награду, но только если сундук открыт. Следите за тем, открыт ли сундук, добавив свойство open.

class LootBox<T>(item: T) {
    var open = false
    private var loot: T = item

    fun fetch(): T? {
        return loot.takeIf { open }
    }
}


Рис.1. Добавление функции fetch() (Generics.kt)

    В примере вы объявили обобщенную функцию fetch(), которая возвращает значение обобщенного типа Т, указанного в определении класса LootBox и служащего заполнителем для вида награды.

    Обратите внимание: если бы fetch() была объявлена вне LootBox, тип Т был бы недоступен, так как Т привязан к объявлению класса LootBox. Однако обобщенные функции не требуют, чтобы класс использовал параметр обобщенного типа. На следующих шагах вы сможете в этом убедиться.

    Попробуйте забрать содержимое lootBoxOne в функции main(), используя вашу новую функцию fetch(), сперва из закрытого сундука.

.   .   .   .
fun main(args: Array<String>) {
    val lootBoxOne: LootBox<Fedora> = LootBox(
            Fedora("a generic-looking fedora", 15))
    val lootBoxTwo: LootBox<Coin> = LootBox(Coin(15))

    lootBoxOne.fetch()?.run {
        println("You retrieve $name from the box!")
    }

}


Рис.2. Тестирование обобщенной функции fetch() (Generics.kt)

    Используйте стандартную функцию run() для вывода названия содержимого lootBoxOne, если оно имеется.

    Вспомните, что run() ограничивает область видимости лямбды, которую принимает, экземпляром объекта-приемника. Это значит, что $name ссылается на свойство name класса Fedora.

    Запустите Generics.kt. Вывода не последует. Вы не смогли забрать награду, так как сундук закрыт. Теперь откройте сундук и снова запустите Generics.kt.

.   .   .   .
fun main(args: Array<String>) {
    val lootBoxOne: LootBox<Fedora> = LootBox(
            Fedora("a generic-looking fedora", 15))
    val lootBoxTwo: LootBox<Coin> = LootBox(Coin(15))
 
        lootBoxOne.open = true    
        lootBoxOne.fetch()?.run {
        println("You retrieve $name from the box!")
    }

}
Файл с проектом можно взять здесь.


Рис.3. Открытие сундука (Generics.kt)

    В этот раз при выполнении Generics.kt вы увидите название полученной награды:

You retrieve a generic-looking fedora from the box!


Рис.4. Полученная награда

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




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