kotlin - Kotlin 构造函数语法设计原理?
问题描述
在我看来,这两个类的行为相同:
class A constructor(ii_: Int) {
var ii = 0
var xx = 0.0F
var msg = ""
init {
ii = ii_
xx = ii + 42.0F
msg = "The value of ii is $ii and the value of xx is $xx"
}
fun display() {
print("A.display() $ii, $xx\n")
print("A.display() $msg\n")
}
}
class C {
var ii = 0
var xx = 0.0F
var msg = ""
constructor(ii_: Int) {
ii = ii_
xx = ii + 42.0F
msg = "The value of ii is $ii and the value of xx is $xx"
}
fun display() {
print("C.display() $ii, $xx\n")
print("C.display() $msg\n")
}
}
如果我不会有多个构造函数,那么使用主构造函数的版本是否有优势?
是否存在我没有看到主要 ctor + init 块方案的理论原因?
带有它的 init 块的主要构造函数版本看起来很巴洛克,这让我认为它有更深层次的原因,但我看不到它。
我知道我的 A 类并不严格需要构造函数关键字。那不是我要问的,请不要打扰告诉我我不需要它。
解决方案
init
块更像是属性初始化器而不是构造器。(如果您了解 Java,它们与 Java 的实例初始化程序几乎相同;请参阅此问题和此讨论。)主要问题是:
你可以有多个
init
块;它们都按顺序运行(连同属性初始化表达式)。如果您使用它们来初始化属性,为了清楚起见,您可以将它们放在它们的属性旁边。它们为每个构造函数运行,因此您无需在构造函数之间复制代码,或者冒着忘记的风险。(它们与属性初始化器一起在调用超类构造函数之后但在构造函数主体的其余部分之前运行。)
它们可以在
object
不允许使用构造函数的表达式和声明中使用。(它们最初被引入 Java 是为了等效于这个,即匿名类。)如果有一个主构造函数,那么它们就可以访问它的参数(尽管不能访问任何辅助构造函数的参数)。(这使得它们比 Java 的实例初始化器更强大。)
推荐阅读
- windows - Powershell - 删除包含排除项的文件夹内容
- python - Google colab 无法读取文件:OSError: [Errno 36] File name too long
- java - 当......然后在临时变量中构造时,是否有可能以某种方式“保持” Mockitos 的返回值?
- javascript - React Router 没有渲染我的组件,但确实将我带到了新的 url 路径?
- ios - 如何通过隐藏导航栏来使用 XLPagerTabStrip 库?
- javascript - 页脚不在应有的下方。我需要它低于所有其他元素
- vba - Basic Visual Basic 程序错误 - 可能是变量/语法错误(标记为 Fat)
- c# - 单击时的 C# 文本框显示下拉列表,其中输入了先前的值
- c++ - 嵌套类模板类型别名
- httprequest - 使用 Power Automate HTTP 请求将列表字段聚合设置为 SUM