微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Kotlin - 从代码字符串评估函数

如何解决Kotlin - 从代码字符串评估函数

一般问题:

我想在 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)

这是可能的,或者可能接近这个结果?

具体问题:

我有一个包含布局和变量地图的活动:

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 实例化布局中的任何类型的视图,从文本到按钮
  • 运行一些特定的安卓命令,如记录、照片等

解决方法

我认为最合理的方法是使用您自己的语言编写解释器。

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,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])
                })
            }
            // ...
        }
    }
}

当然这只是一个想法,您还需要处理可能发生的无效命令和异常。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。