Несколько контекстов в Kotlin
Одна операция может опираться сразу на два сервиса -
например, журнал и форматирование текста. Для
этого в context перечисляют несколько
пар имя-тип через запятую.
Класс Logger пишет строку как есть, а
Labeler оборачивает имя в квадратные
скобки. Функция publish использует оба
имени из контекста:
class Logger {
fun write(text: String) {
println(text)
}
}
class Labeler {
fun wrap(name: String): String = "[$name]"
}
context(logger: Logger, labeler: Labeler)
fun publish(name: String) {
logger.write(labeler.wrap(name))
}
Блок context принимает столько значений,
сколько параметров в объявлении функции. Порядок
аргументов в блоке совпадает с порядком имен
в context перед fun:
fun main() {
val logger = Logger()
val labeler = Labeler()
context(logger, labeler) {
publish("api")
}
}
Оба типа в одном объявлении остаются независимыми: функция может вызывать методы каждого объекта по своему имени, как две обычные переменные в теле.
Объявите Clock с методом nowLabel,
возвращающим строку "morning", и
Banner с методом frame для
обрамления текста. Функция header с
двумя контекстами выводит через Logger
рамку вокруг метки времени.
Добавьте функцию publishPair с теми же
двумя контекстами, что у publish: она
дважды пишет в журнал разные метки через
labeler.wrap. Проверьте в одном блоке
context.