kotlin - 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
...
}
我尝试了几种方法(委托、类等),但没有一个提供这些语法。
有没有办法声明这个类似联合的结构?
解决方案
您如何看待以下语法:
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
}
}
推荐阅读
- c# - 尝试将子类添加到 Fhir.Net 资源并对其进行序列化?
- javascript - 将 HTML 元素添加为 document.documentElement 的直接子元素有什么问题吗?
- json - 雅虎关闭后,YQL 查询服务替换
- css - 如何正确设置 SVG 图像的样式
- python - 如何在python pptx中将两个图像添加到一张幻灯片
- python - 如果语句不起作用,python
- python - Pytest 抛出警告字符串>:1: DeprecationWarning: invalid escape sequence \s
- r - R:如何在远程服务器中使用 sftp 检查文件是否存在
- java - Apache Beam S3 文件系统扩展始终需要 aws 区域输入,即使在我的项目中不使用 AWS 的其他管道中也是如此
- lua - 如何在给定新 ID 的情况下创建新文件?