Как создать переменные в родительском контексте

Я пытаюсь реализовать что-то похожее на этот синтаксис в Kotlin

class MyClass() {
    fun before(init: () -> Unit): Unit {
        with(this) init
    }
    fun after(block: () -> Unit): Unit {
        with(this) block
    }
}

fun main () {
    var myClass = MyClass()
    myClass.before {
        var a = 5
    }
    myClass.after {
        println("Double of a is ${a * 2}")
    }
}

Сейчас это не сработает, потому что a не может быть решена в течение after, Я понимаю, что это связано с тем, как работают крышки.

Мой вопрос: есть ли в Kotlin какой-нибудь механизм, который позволил бы мне сделать это, создать переменные в замыкании / расширении таким образом, чтобы они были сохранены в объекте-получателе и были доступны для других замыканий / расширений.

Это часть усилий по переносу скрипта Groovy в Kotlin.

Отказ от ответственности: это мой самый первый поход в Котлин. Я прочитал документы, но я могу что-то упустить (много). Не стесняйтесь просто указывать в правильном направлении

РЕДАКТИРОВАТЬ: Добавление скомпилированного примера

class Aa() {

    var a: Int = 0
    var bb: () -> Unit = null!!

    fun ww (block: () -> Unit) {
        bb = block
    }

    fun doit(block: () -> Unit) {
        with(bb) {
            block()
        }
    }

}

fun main(args: Array<String>) {
    val exec = fun Aa.(other: () -> Unit): Unit = other()

    aa.ww {
        var xx = 5
    }

    aa.doit {
        // println("with $xx") <- this fails
    }
}

1 ответ

Решение

Котлин - статически типизированный язык. Невозможно хранить данные внутри экземпляра объекта, для которого нет поля внутри этого объекта.

Вы можете определить свойство типа Mapи сохраните значения внутри этой карты, но вы не сможете получить к ним доступ, используя обычный синтаксис свойств, если заранее не знаете, какие значения будут там храниться.

Другие вопросы по тегам