Kotlin - 从代码字符串评估函数
Kotlin - Evaluate functions from code string
一般问题:
我想 运行 在 kotlin 应用程序中将一些代码存储为字符串。
fun Evaluate(str: String,f:(s : String) -> Unit )
{
f(str)
}
例如,一个 Hello World
var function : String = "fun a(s:String) = println(s)"
Evaluate ("Hello World",function)
这可能吗,或者可能接近这个结果?
具体问题:
我有一个 activity 包含布局和变量映射:
private lateinit var glayout: LinearLayout
val variable : MutableMap<String, Any> = mutableMapOf(),
val code : List<String>
override fun onCreate(savedInstanceState: Bundle?) {
//Some init
glayout = binding.root.findViewById(R.id.gamelayout)
code = getCodeFromJson()
for (c in code){
//Here execute the code
}
}
所以我希望能够在我的解释代码中:
- 修改地图中的一个变量
- 使用 onClickListener 实例化布局中的任何类型的视图,从文本到按钮
- 运行 一些特定的 android 命令,如记录、照片等
我认为最合理的方式是用你自己的语言写一个解释器。
abstract class Interpreter {
fun run(sentence: String) {
val input = sentence.trim().split(" ")
val cmd = input[0]
val args = input.drop(1)
execute(cmd, args)
}
protected abstract fun execute(command: String, args: List<String>)
}
例如,如果您有一张地图并且希望用户修改它:
class MapInterpreter(private val map: MutableMap<String, String>) : Interpreter() {
override protected fun execute(command: String, args: List<String>) {
when (command) {
"putmap" -> {
require(args.size == 2) { "usage: addmap [key] [value]" }
map[args[0]] = args[1]
}
"remmap" -> {
require(args.size == 1) { "usage: remmap [key]" }
map.remove(args[0])
}
"showmap" -> {
require(args.size == 0) { "usage: showmap" }
println(map)
}
}
}
}
要使用它,只需使用用户输入(例如从文本字段)调用 run
方法:
val map: MutableMap<String, String> = hashMapOf()
val interpreter = MapInterpreter(map)
interpreter.run("putmap I one")
interpreter.run("putmap V five")
interpreter.run("putmap X ten")
interpreter.run("putmap 2 two")
interpreter.run("showmap")
interpreter.run("remmap 2")
interpreter.run("showmap")
// Output:
// {2=two, V=five, X=ten, I=one}
// {V=five, X=ten, I=one}
另一个例子;动态实例化 Android 视图:
class ViewBuilderInterpreter(private val context: Context, private val parent: View) : Interpreter() {
override protected fun execute(command: String, args: List<String>) {
when (command) {
"textview" -> {
require(args.size >= 1 && args.size <= 2) { "usage: textview [text] {color}" }
parent.addView(Text(context).also {
it.text = args[0]
it.color = if (args.size == 1) Color.BLACK else Color.parseColor(args[1])
})
}
// ...
}
}
}
当然这只是一个想法,你还需要处理无效命令和可能发生的异常。
一般问题:
我想 运行 在 kotlin 应用程序中将一些代码存储为字符串。
fun Evaluate(str: String,f:(s : String) -> Unit )
{
f(str)
}
例如,一个 Hello World
var function : String = "fun a(s:String) = println(s)"
Evaluate ("Hello World",function)
这可能吗,或者可能接近这个结果?
具体问题:
我有一个 activity 包含布局和变量映射:
private lateinit var glayout: LinearLayout
val variable : MutableMap<String, Any> = mutableMapOf(),
val code : List<String>
override fun onCreate(savedInstanceState: Bundle?) {
//Some init
glayout = binding.root.findViewById(R.id.gamelayout)
code = getCodeFromJson()
for (c in code){
//Here execute the code
}
}
所以我希望能够在我的解释代码中:
- 修改地图中的一个变量
- 使用 onClickListener 实例化布局中的任何类型的视图,从文本到按钮
- 运行 一些特定的 android 命令,如记录、照片等
我认为最合理的方式是用你自己的语言写一个解释器。
abstract class Interpreter {
fun run(sentence: String) {
val input = sentence.trim().split(" ")
val cmd = input[0]
val args = input.drop(1)
execute(cmd, args)
}
protected abstract fun execute(command: String, args: List<String>)
}
例如,如果您有一张地图并且希望用户修改它:
class MapInterpreter(private val map: MutableMap<String, String>) : Interpreter() {
override protected fun execute(command: String, args: List<String>) {
when (command) {
"putmap" -> {
require(args.size == 2) { "usage: addmap [key] [value]" }
map[args[0]] = args[1]
}
"remmap" -> {
require(args.size == 1) { "usage: remmap [key]" }
map.remove(args[0])
}
"showmap" -> {
require(args.size == 0) { "usage: showmap" }
println(map)
}
}
}
}
要使用它,只需使用用户输入(例如从文本字段)调用 run
方法:
val map: MutableMap<String, String> = hashMapOf()
val interpreter = MapInterpreter(map)
interpreter.run("putmap I one")
interpreter.run("putmap V five")
interpreter.run("putmap X ten")
interpreter.run("putmap 2 two")
interpreter.run("showmap")
interpreter.run("remmap 2")
interpreter.run("showmap")
// Output:
// {2=two, V=five, X=ten, I=one}
// {V=five, X=ten, I=one}
另一个例子;动态实例化 Android 视图:
class ViewBuilderInterpreter(private val context: Context, private val parent: View) : Interpreter() {
override protected fun execute(command: String, args: List<String>) {
when (command) {
"textview" -> {
require(args.size >= 1 && args.size <= 2) { "usage: textview [text] {color}" }
parent.addView(Text(context).also {
it.text = args[0]
it.color = if (args.size == 1) Color.BLACK else Color.parseColor(args[1])
})
}
// ...
}
}
}
当然这只是一个想法,你还需要处理无效命令和可能发生的异常。