首页 > 解决方案 > Kotlin DSL - 联合结构

问题描述

我正在设计一个 DSL 并遇到一个要求,我有一个可以分配给不同方式的变量。大大简化,我想value通过整数或字符串中的表达式设置属性。(真正的需求更加复杂。)

我想在我的 DSL 中写:

value = 42

或者

value = "6*7"

在幕后,该值将存储在一个DynamicValue<Int>包含整数或表达式的结构中。

class DynamicValue<T>(dv : T?, expr : String) {
    val directValue : T? = dv
    val script : String? = expr
    ...
}

我尝试了几种方法(委托、类等),但没有一个提供这些语法。

有没有办法声明这个类似联合的结构?

标签: kotlingradle-kotlin-dsl

解决方案


您如何看待以下语法:

value(42)
value("6*7")
//or
value+=42
value+="6*7"

您可以使用运算符函数执行此操作:

class DynamicValue<T>() {
    var dv: T? = null
    var expr: String? = null

    operator fun invoke(dv : T)  {
        this.dv = dv
        this.expr = null
    }

    operator fun invoke(expr: String)  {
        this.dv = null
        this.expr = expr
    }

    operator fun plusAssign(dv : T)  {
        this.dv = dv
        this.expr = null
    }

    operator fun plusAssign(expr: String)  {
        this.dv = null
        this.expr = expr
    }
}  

您不能在 Kotlin 中重新定义赋值运算符,因此纯语法value=42是不可能的。

但我不会使用运算符功能,它太神奇了。我会这样做:

val value = DynamicValue<Int>()
value.simple=42
value.expr="6*7"

class DynamicValue2<T>() {
    private var _dv: T? = null
    private var _expr: String? = null
    var simple: T?
        get() = _dv
        set(value) {
            _dv = value
            _expr = null
        }

    var expr: String?
        get() = _expr
        set(value) {
            _expr = value
            _dv = null
        }
}

推荐阅读