Kotlin DSL变量模拟

Kotlin DSL变量模拟,kotlin,dsl,kotlin-dsl,Kotlin,Dsl,Kotlin Dsl,使用Kotlin类型安全构建器可能最终会编写此代码 code { dict["a"] = "foo"; // dict is a Map hidden inside that can associate some name to some value println(dict["a"]); // usage of this value } 这段代码还可以,但有一个问题:“a”只是一个字符串。我希望它像一个用户定义的变量——一个由编译器识别的标识符,启用自动完成 有没有办法把它变成这样

使用Kotlin类型安全构建器可能最终会编写此代码

code {
  dict["a"] = "foo"; // dict is a Map hidden inside that can associate some name to some value
  println(dict["a"]); // usage of this value
}
这段代码还可以,但有一个问题:“a”只是一个字符串。我希望它像一个用户定义的变量——一个由编译器识别的标识符,启用自动完成

有没有办法把它变成这样

code {
  a = "foo"; // now 'a' is not a Map key, but an identifier recognized by Kotlin as a variable name
  println(a);
}
如果我将
code
的lambda设置为某个对象上的扩展函数,并在其中定义了一个
a
,我就可以做到这一点。这不是我想要的。我希望能够使用其他变量(名称未知)以及

一个可能的解决办法是

code {
  var a = v("a", "foo");
  println(a);
}
其中
v
是扩展对象的一个方法,它将值“foo”存储在“dict”中,并返回该值的句柄


这个案例几乎完美,但它能更清晰/更好吗?

您可以使用属性委托:

class Code {
    private val dict = mutableMapOf<String, String>()

    operator fun String.provideDelegate(
        thisRef: Any?,
        prop: KProperty<*>
    ): MutableMap<String, String> {
        dict[prop.name] = this
        return dict
    }
}

您可以使用属性委派:

class Code {
    private val dict = mutableMapOf<String, String>()

    operator fun String.provideDelegate(
        thisRef: Any?,
        prop: KProperty<*>
    ): MutableMap<String, String> {
        dict[prop.name] = this
        return dict
    }
}