Kotlin:辅助构造函数参数上不允许使用“val”

问题描述 投票:0回答:4

我有以下课程:

class Person(val name: String) {
    private var surname: String = "Unknown"

    constructor(name: String, surname: String) : this(name) {
        this.surname = surname
    }
}

但是当我想让 name 参数在第二个构造函数中不可变时:

constructor(val name: String, surname: String) : this(name) {
    this.surname = surname
}

我有以下编译时错误:

Kotlin:辅助构造函数参数上不允许使用“val”

有人可以解释为什么 Kotlin 编译器不允许这样做吗?

constructor kotlin
4个回答
32
投票

Kotlin 中的参数始终是不可变的。将构造函数参数标记为

val
会将其转换为类的属性,并且这只能在主构造函数中完成,因为类的属性集不能根据用于创建类实例的构造函数而变化类。


4
投票

除了yole的精彩答案之外,文档也非常清晰:

请注意,主构造函数的参数可以在初始化块中使用。它们还可以用在类主体中声明的属性初始值设定项中。 [...] 事实上,为了声明属性并从主构造函数初始化它们,Kotlin 具有简洁的语法:

class Person(val firstName: String, val lastName: String, var age: Int) {
    // ...
}

与常规属性非常相似,在主构造函数中声明的属性可以是可变的 (var) 或只读 (val)。

这一切不适用于辅助构造函数。


1
投票

当前接受的答案正确地解释了为什么您最初的尝试不起作用。因此,考虑到您的特定场景,我将反转解决方案并使您的辅助构造函数成为主要构造函数,并使第二个参数具有默认值。

data class Person(val name: String, val surname: String = "Unknown")

此外,如果该类的目的只是保存数据,我会将其设为

data class
以改进其处理能力。


0
投票

您可以在继承的类中将变量定义为 val 或 var

   open class Human(val name: String) constructor(name: String) {
            open fun showInfo()
        {
            println("Show Info")
        }
        }

class Person:Human {

constructor(name: String) : super(name)
    private var surname: String = "Unknown"
  override fun showInfo() {
        println("$name And surname is $surname")
    }
    
}
© www.soinside.com 2019 - 2024. All rights reserved.