Kotlin DSL变量模仿
Kotlin DSL variable imitation
使用 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" 中,并且 returns 是该值的句柄。
这个案例几乎是完美的,但能不能clearer/better不知何故?
您可以使用属性委托:
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
}
}
用例:
code {
var a by "foo" // dict = {a=foo}
println(a) // foo
a = "bar" // dict = {a=bar}
println(a) // bar
}
使用 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" 中,并且 returns 是该值的句柄。
这个案例几乎是完美的,但能不能clearer/better不知何故?
您可以使用属性委托:
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
}
}
用例:
code {
var a by "foo" // dict = {a=foo}
println(a) // foo
a = "bar" // dict = {a=bar}
println(a) // bar
}