gpt4 book ai didi

kotlin - 从 DSL block 中的语句创建列表

转载 作者:行者123 更新时间:2023-12-02 12:54:49 25 4
gpt4 key购买 nike

在尝试构建用于验证的 DSL 时,我正在寻找方法来收集带有接收器的 block /lambda 中的语句。为了说明,这是一个没有实际验证逻辑的最小示例:

data class Constraint(val hint: String)

class Validation(val constraints: List<Constraint>) {

companion object {
operator fun invoke(init: (ValidationBuilder.() -> Unit)): Validation {
return ValidationBuilder().apply(init).build()
}
}

class ValidationBuilder {
private var constraints: MutableList<Constraint> = mutableListOf()

operator fun Constraint.unaryPlus() {
constraints.add(this)
}

fun build() = Validation(constraints)
}
}

然后可以使用它来构建这样的验证
val validation = Validation {
+Constraint("First constraint")
val secondConstraintHint = "Second constraint"
+Constraint(secondConstraintHint)
}

我想摆脱 unaryPlus运算符并直接收集 block 中评估为 Constraint 的各个语句这样我就可以做类似的事情:
val validation = Validation {
Constraint("First constraint")
val secondConstraintHint = "Second constraint"
Constraint(secondConstraintHint)
}

这有可能吗?

为了提供更多背景信息,我想要的实际结果看起来更像这样:
Validation<User> {
User::firstName {
val min = 2
minLength(min) hint "Please provide a first name"
maxLength(200) // uses default hint
}
}

最佳答案

好吧,似乎没有直接的解决方案,因为 Kotlin 无法处理未在任何地方分配、返回或传递的评估表达式结果。

一种可能的解决方法是使用为您的构建器定义的函数来模拟您需要的构造函数:

class ValidationBuilder {
/* ... */

fun Constraint(name: String) =
full.qualified.name.of.Constraint(name).also(constraints::add)
}

不幸的是,这将要求您复制要以这种方式调用的所有签名。

UPD(回复评论) :我相信用户自定义 DSL 的惯用方式是为 DSL 构建器定义自己的扩展:
fun ValidationBuilder.nonEmptyText(min: Int = 1, max: Int = 65.536) = TODO()

如果一个 Constraint来自 DSL 之外的应用程序是一个重要的用例,您可以使用特殊功能(例如 fun ValidationBuilder.constraint(...) )覆盖它,并让用户将他们的扩展委托(delegate)给它。

关于kotlin - 从 DSL block 中的语句创建列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49131737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com