我知道数据类就像kotlin中的简单模型一样,默认情况下使用getter和setter,就像这样简单:
data class User(val name: String, val age: Int)
是否可以为该数据类声明第二个构造函数?
答案 0 :(得分:17)
是的,但是应该初始化每个变量,因此您可以在数据类构造函数中设置默认参数,如下所示:
data class Person(val age: Int, val name: String = "Person without name")
现在您可以通过两种方式创建此数据类的实例
Person(30)
Person(20, "Bob")
答案 1 :(得分:15)
Kotlin数据类必须具有定义至少一个成员的主构造函数。除此之外,您可以按照Classes and Inheritance - Secondary Constructors中的说明添加辅助构造函数。
对于您的类和示例辅助构造函数:
data class User(val name: String, val age: Int) {
constructor(name: String): this(name, -1) { ... }
}
请注意,辅助构造函数必须在其定义中委托给主构造函数。
虽然辅助构造函数的许多共同点可以通过为参数设置默认值来解决。在上面的例子中,您可以简化为:
data class User(val name: String, val age: Int = -1)
如果从Java调用这些文件,您应阅读有关如何生成重载的Java interop - Java calling Kotlin文档,有时可能阅读其他特殊情况的NoArg Compiler Plugin文档。
答案 2 :(得分:3)
更新了数据类的答案:
是的,您可以,但您需要将所有内容委托给主要构造函数
data class User(val name: String, val age: Int)
{
constructor(name: String): this(name, -1) {
}
constructor(age: Int): this("Anon", age) {
}
}
// Anon name: Anon
println("Anon name: " + User(30).name)
// No age: -1
println("No age: " + User("Name").age)
// Name: Name age: 20
val u = User("Name", 20)
println("Name: " + u.name + " age: " + u.age)
您也可以像Alexey那样在主构造函数中设置默认值。
答案 3 :(得分:3)
我想拥有一个与下面类似的类(具有解析输入的构造函数)
data class Data(val a: String, val b: String) {
constructor(spaceSeparated: String) { // error because we don't call this()
val split = spaceSeparated.split(" ")
this(split.first(), split.last()) // error again because it's not valid there
}
}
解决方案是这样做:
data class Data(val a: String, val b: String) {
companion object {
operator fun invoke(spaceSeparated: String): Data {
val split = spaceSeparated.split(" ")
return Data(split.first(), split.last())
}
}
}
它可以像构造函数一样被调用
答案 4 :(得分:2)
您可以像这样设置数据类
data class User(val name: String? = null, val id: String? = null, val email: String? = null)
并且您可以使用这样的多个构造方法来实例化该对象
val userId = User(id = "123456")
val userMail = User(email= "email@email.com")
val userName = User("Name")
答案 5 :(得分:1)
是的,我们可以使用类似下面的代码,并且在数据类的主构造函数中应该有min一个参数。
data class SampleData(val name: String, val age: Int) {
constructor(name: String, age: Int, email: String) : this(name, age) {
}
}
答案 6 :(得分:1)
指示Kotlin编译器为此函数生成替换默认参数值的重载。 如果一个方法有N个参数,其中M个具有默认值,则会生成M个重载:第一个重载使用N-1个参数(除了最后一个具有默认值),第二个重载N-2个参数,依此类推上。
data class User @JvmOverloads constructor(
var email: String="",
var password: String=""
)
答案 7 :(得分:0)
数据类将确保一致性和有意义的行为,我们还需要具有不可变性的val。
data class SampleData(val name: String, val age: Int, val email: String ?= null) {
constructor(name: String, age: Int) : this(name, age, null) {
}
}
辅助构造函数必须在其定义中委托给主构造函数,因此要保持不变性,“null”将起作用。
答案 8 :(得分:0)
主构造函数中的默认值消除了对辅助构造函数的许多需求,但是如果所需实例取决于基于必须分析的数据的逻辑,则更好的答案可能是使用伴随对象。
data class KeyTag(val a: String, val b: Int, val c: Double) {
companion object Factory {
val empty = KeyTag("", 0, 0.0)
fun create(bigString: String): KeyTag {
// Logic to extract appropriate values for arguments a, b, c
return KeyTag(a, b, c)
}
fun bake(i: Int): KeyTag = KeyTag("$i", i, i.toDouble())
}
}
当时的用法是
val ks = KeyTag.create("abc:1:10.0")
val ke = KeyTag.empty
val kb = KeyTag.bake(2)
答案 9 :(得分:0)
是的,您可以在数据类上拥有多个承包商。但是有一些东西使 primary constructor
很特别。编译器将根据数据类的 equals
自动生成 hashCode
、copy
、toStrings
、primary constructor
等方法。
下面是一个数据类的两个实例的示例,它们看起来不同(first.gender =male,second.gender =female)但 equals
方法将评估为 true
因为 {{1} } 未在主构造函数中定义,因此未在自动生成的方法中考虑。同样,性别不会包含在字符串表示中。
gender