G_H*_*G_H 2 templates dynamic kotlin
假设我有以下Kotlin代码:
fun main(args: Array<String>) {
val a = "test"
println(args.first())
}
Run Code Online (Sandbox Code Playgroud)
如果我传入一个参数$a,输出将是$a.据我了解,Kotlin通过在编译时生成输出代码来处理String模板,可能是使用StringBuilder.有没有办法在当前上下文中评估关于模板的源代码中没有的字符串?字符串模板非常有用,能够评估来自动态上下文的表达式(例如配置文件)会很棒,但据我所知,这是不可能的.
缺乏这一点,对此有什么好处?调用脚本引擎?
Mic*_*hli 14
为了完整起见,这里还提供了一些在 Kotlin 代码中动态评估字符串模板的方法。
字符串模板的正常行为是在编译时评估字符串的内容。在代码执行期间它不会改变:
fun main() {
var subject = "world"
val hello = "hello $subject"
subject = "stackoverflow"
println(hello)
}
// Output: hello world
Run Code Online (Sandbox Code Playgroud)
针对此限制有多种解决方法:
您可以将 String 包装在 lambda 函数中,因此每次调用函数时,它都会评估 String 的新实例。
fun main() {
var subject = "world"
val hello = {"hello $subject"}
subject = "stackoverflow"
println(hello())
}
// Output: hello stackoverflow
Run Code Online (Sandbox Code Playgroud)
优势
坏处
您可以创建匿名对象(类似于Java中的static)并重写toString方法。
fun main() {
var subject = "world"
val hello = object { override fun toString() = "hello $subject"}
subject = "stackoverflow"
println(hello())
}
// Output: hello stackoverflow
Run Code Online (Sandbox Code Playgroud)
注意:我不推荐这种方法。
优势
坏处
您可以将属性运算符函数委托给外部类,以实现 String 模板的动态计算。
import kotlin.reflect.KProperty
fun main() {
var subject = "world"
val hello: String by dynamicStringTemplate { "hello $subject" }
subject = "stackoverflow"
println(hello)
}
// Output: hello stackoverflow
class dynamicStringTemplate(var value: () -> String) {
operator fun getValue(thisRef: Nothing?, prop: KProperty<*>): String {
return this.value()
}
operator fun setValue(thisRef: Nothing?, prop: KProperty<*>, value: String) {
this.value = {value}
}
}
Run Code Online (Sandbox Code Playgroud)
优点
坏处
如果您需要以这种方式评估任意表达式,那么是的,您需要一个脚本引擎.Kotlin有一个可以使用的JSR 223实现,请参阅此处kotlin-jsr223-*的示例(项目).
这是一个基本的用法示例:
val engine = ScriptEngineManager().getEngineByExtension("kts")!!
engine.eval("val x = 3")
val res = engine.eval("x + 2")
Assert.assertEquals(5, res)
Run Code Online (Sandbox Code Playgroud)
代码取自KotlinJsr223ScriptEngineIT.kt,并记得通过配置服务META-INF
| 归档时间: |
|
| 查看次数: |
3057 次 |
| 最近记录: |