我正在尝试创建一个用于创建JSONObjects的DSL.这是一个构建器类和一个示例用法:
import org.json.JSONObject fun json(build: JsonObjectBuilder.() -> Unit): JSONObject { val builder = JsonObjectBuilder() builder.build() return builder.json } class JsonObjectBuilder { val json = JSONObject() infix funString.To(value: T) { json.put(this, value) } } fun main(args: Array ) { val jsonObject = json { "name" To "ilkin" "age" To 37 "male" To true "contact" To json { "city" To "istanbul" "email" To "xxx@yyy.com" } } println(jsonObject) }
上面代码的输出是:
{"contact":{"city":"istanbul","email":"xxx@yyy.com"},"name":"ilkin","age":37,"male":true}
它按预期工作.但它每次创建一个json对象时都会创建一个额外的JsonObjectBuilder实例.是否可以编写DSL来创建json对象而无需额外的垃圾?
您可以使用Deque作为堆栈来JSONObject
使用单个跟踪当前上下文JsonObjectBuilder
:
fun json(build: JsonObjectBuilder.() -> Unit): JSONObject { return JsonObjectBuilder().json(build) } class JsonObjectBuilder { private val deque: Deque= ArrayDeque() fun json(build: JsonObjectBuilder.() -> Unit): JSONObject { deque.push(JSONObject()) this.build() return deque.pop() } infix fun String.To(value: T) { deque.peek().put(this, value) } } fun main(args: Array ) { val jsonObject = json { "name" To "ilkin" "age" To 37 "male" To true "contact" To json { "city" To "istanbul" "email" To "xxx@yyy.com" } } println(jsonObject) }
示例输出:
{"contact":{"city":"istanbul","email":"xxx@yyy.com"},"name":"ilkin","age":37,"male":true}
在单个上调用json
和build
跨多个线程JsonObjectBuilder
会有问题,但这不应该是您的用例的问题.
你需要DSL吗?你失去了执行String
密钥的能力,但香草Kotlin并不是那么糟糕:)
JSONObject(mapOf( "name" to "ilkin", "age" to 37, "male" to true, "contact" to mapOf( "city" to "istanbul", "email" to "xxx@yyy.com" ) ))