当前位置:  开发笔记 > 前端 > 正文

用于创建json对象的Kotlin DSL(无需创建垃圾)

如何解决《用于创建json对象的KotlinDSL(无需创建垃圾)》经验,为你挑选了2个好方法。

我正在尝试创建一个用于创建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 fun  String.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对象而无需额外的垃圾?



1> mfulton26..:

您可以使用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}

在单个上调用jsonbuild跨多个线程JsonObjectBuilder会有问题,但这不应该是您的用例的问题.



2> James Basset..:

你需要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"
        )
))


我同意,这个版本已经看起来像DSL了.但它会创建临时数组和对.
推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有