Kotlin DSL用于创建json对象(不创建垃圾)

我正在尝试创建一个DSL来创建 JSONObjects.这是一个构建器类和示例用法
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 <T> String.To(value: T) {
        json.put(this,value)
    }
}

fun main(args: Array<String>) {
    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作为堆栈,以使用单个JsonObjectBuilder来跟踪当前的JSONObject上下文:
fun json(build: JsonObjectBuilder.() -> Unit): JSONObject {
    return JsonObjectBuilder().json(build)
}

class JsonObjectBuilder {
    private val deque: Deque<JSONObject> = arraydeque()

    fun json(build: JsonObjectBuilder.() -> Unit): JSONObject {
        deque.push(JSONObject())
        this.build()
        return deque.pop()
    }

    infix fun <T> String.To(value: T) {
        deque.peek().put(this,value)
    }
}

fun main(args: Array<String>) {
    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","male":true}

调用json并在单个JsonObjectBuilder上跨多个线程构建将是有问题的,但这不应该是您的用例的问题.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...