我有一个静态编程语言数据类,我正在用许多不可变属性构建它,这些属性是从单独的SQL查询中获取的。如果我想使用构建器模式构建数据类,如何在不使这些属性可变的情况下做到这一点?
例如,而不是通过构造
var data = MyData(val1, val2, val3)
我想用
builder.someVal(val1)
// compute val2
builder.someOtherVal(val2)
// ...
var data = builder.build()
同时仍然使用Kotlin的数据类特性和不可变属性。
无需在静态编程语言中创建自定义构建器-为了实现类似构建器的语义学,您可以利用复制
方法-它非常适合您想要通过少量更改获得对象副本的情况。
data class MyData(val val1: String? = null, val val2: String? = null, val val3: String? = null)
val temp = MyData()
.copy(val1 = "1")
.copy(val2 = "2")
.copy(val3 = "3")
或:
val empty = MyData()
val with1 = empty.copy(val1 = "1")
val with2 = with1.copy(val2 = "2")
val with3 = with2.copy(val3 = "3")
由于您希望一切都是不可变的,因此复制必须在每个阶段进行。
此外,只要生成器生成的结果是不可变的,在生成器中具有可变属性也可以。
我认为科特林没有原生建筑商。您始终可以计算所有值并在末尾创建对象。
如果你仍然想使用构建器,你必须自己实现它。检查这个问题
我同意Grzegorz答案中的数据复制块,但它本质上与使用构造函数创建数据类的语法相同。如果您想使用这种方法并保持所有内容清晰易读,您可能会事先计算所有内容并最终将所有值一起传递。
要拥有更像构建器的东西,您可以考虑以下几点:
假设您的数据类是
data class Data(val text: String, val number: Int, val time: Long)
您可以像这样创建可变构建器版本,并使用构建方法来创建数据类:
class Builder {
var text = "hello"
var number = 2
var time = System.currentTimeMillis()
internal fun build()
= Data(text, number, time)
}
以及像这样的构建器方法:
fun createData(action: Builder.() -> Unit): Data {
val builder = Builder()
builder.action()
return builder.build()
}
Action是一个函数,您可以从中直接修改值,createData
将在之后直接为您将其构建为数据类。这样,您可以使用以下方式创建数据类:
val data: Data = createData {
//execute stuff here
text = "new text"
//calculate number
number = -1
//calculate time
time = 222L
}
比方说,没有setter方法,但是您可以用新值直接给可变变量赋值,并在构建器中调用其他方法。
您还可以通过为每个变量指定自己的函数来利用 kotlin 的 get 和 set,这样它就可以做更多的事情,而不仅仅是设置字段。
也不需要返回当前的构建器类,因为您始终可以访问它的变量。
附加说明:如果您愿意,createData
可以缩短为:
fun createData(action: Builder.() -> Unit): Data = with(Builder()) { action(); build() }.
“有了新的建设者,应用我们的行动并构建”
我们知道,要创建不可变类,我们需要将一个类声明为final,需要将所有字段声明为final,并且该类中不应该存在任何setter方法。我们需要在构造函数中初始化那些字段。 但是当我们有10多个字段或者更多字段的时候会发生什么呢?我们不能传递构造函数中的所有字段,对吧?在这个场景中,我们如何创建一个不可变的类呢?
我想在Kotlin中为具有不可变属性的类型使用类型安全生成器。 我想到了两种解决方案: 选项 1:创建生成器类: 选项2:创建自定义委托以防止再次设置该值: 选项1的缺点是我必须维护两个类,选项2的缺点是编译器将允许再次设置< code>DataClass中的值,并且检查将只在运行时进行。 有没有更好的方法来解决这个问题而没有提到的缺点?
我试图学习数组对象在Java但不明白。我确实明白如何将输入存储到数组对象中,但不明白如何比较数组中的每个项来做#7和#8。我试图在网上搜索,但从那里卡住了。 > 创建具有以下属性的班级学生:姓名、年龄、地址、电子邮件地址 创建一个空构造函数,用于初始化所有属性的空值。 创建一个接受所有参数并初始化所有属性的构造函数。 为所有属性创建访问器和变异器方法。 创建一个toString方法以返回学生的详细
问题内容: 情况: 我有一个带有字段的类,因此它们不在构造函数中: 我想拥有一个包含所有字段的方法,并且不想手动编写它,以避免锅炉打印。在Java中,我将使用 Lombok 注释解决此问题。 题: 有什么方法可以在Kotlin中实施吗? 问题答案: 推荐的方法是手动编写(或由IDE生成),并希望您没有太多这样的类。 目的是为了适应最常见的85%的情况,而剩下15%留给其他解决方案。
我对Kotlin很陌生,并试图将一个项目从Java迁移到它。我对Kotlin的属性和它们的getters/setter以及可见性范围有点困惑。 我想要实现的是: 所以基本上我需要创建一个具有私有属性的类。此属性应由公共 getter 访问,但它不应具有 setter。此外,此属性应该是内部可变的,以便可以使用某种方法(如 更改其值。 据我所知,我不能将其声明为,因为在这种情况下,它将是完全不可变的
Kotlin有一个const关键字。但我不认为kotlin中的常数是我所认为的。这似乎与C中的const非常不同。在我看来,its仅适用于静态成员和Java中的原语,不针对类变量进行编译: 由于这似乎不起作用,我认为我真正想要的是第二个类,它删除我不想支持的操作: 这种方法的明显缺点是,我不能忘记更改这个类,以防我更改,这对我来说非常危险。 但是我不确定如何做到这一点。所以问题是:如何用意识形态静