Явный аргумент в Kotlin
Если в области видны два объекта одного типа,
компилятор не выберет, какой подставить в
контекстную функцию. Типичный случай - две
перегрузки с разными именами параметра, но
одним типом Logger.
Стабильный способ - открыть блок context
ровно с одним нужным экземпляром и вызвать
функцию внутри. Так не остается двусмысленности:
class Logger {
fun write(text: String) {
println(text)
}
}
context(mainLog: Logger)
fun note(text: String) {
mainLog.write("main: $text")
}
context(copyLog: Logger)
fun note(text: String) {
copyLog.write("copy: $text")
}
fun main() {
val mainLog = Logger()
val copyLog = Logger()
context(mainLog) {
note("ready")
}
}
Экспериментальная форма передает контекст
именованным аргументом прямо в вызове функции
note. Она не включена по умолчанию: нужен
флаг компилятора -Xexplicit-context-arguments.
С флагом в одной области можно указать, какой
Logger пойдет в какую перегрузку, не
заворачивая каждый вызов в отдельный блок:
fun main() {
val mainLog = Logger()
val copyLog = Logger()
note(mainLog = mainLog, "ready")
note(copyLog = copyLog, "saved")
}
Без -Xexplicit-context-arguments второй
фрагмент не компилируется, хотя первый остается
рабочим на обычных настройках проекта. Имена
mainLog и copyLog совпадают с
именами контекстных параметров в объявлениях
note.
Скопируйте две перегрузки note и
вызовите каждую через свой блок context
без флага. Выведите две разные префикса в
консоль.
Подключите -Xexplicit-context-arguments
и повторите оба вызова одной строкой каждый,
с именованным контекстом. Сравните текст
вывода с вариантом на блоках.