【问题标题】:Is it possible to use a private secondary constructor to assign a val in Kotlin?是否可以使用私有辅助构造函数在 Kotlin 中分配 val?
【发布时间】:2022-01-04 15:01:03
【问题描述】:

我试图通过使用私有构造函数来分配类字段来减少代码重复,但这似乎是不可能的。

我想要做的就是这里的例子:

class Foo {
    private val bar: Int
    private val baz: Int

    constructor(bar: Int, baz: Int) : this(baz) {
        this.bar = bar
    }

    constructor(bar: String, baz: Int) : this(baz) {
        this.bar = bar.toInt()
    }

    private constructor(baz: Int) {
        this.baz = baz
    }
}

可行但我不满意的替代方法是执行以下操作:

class Foo {
    private val bar: Int
    private val baz: Int

    constructor(bar: Int, baz: Int) {
        this.bar = bar
        this.baz = baz
    }

    constructor(bar: String, baz: Int) {
        this.bar = bar.toInt()
        this.baz = baz
    }
}

需要明确的是,由于 this.baz 分配的复制,我不满意。

这在 Kotlin 中根本不可能,还是我遗漏了什么?

【问题讨论】:

    标签: kotlin constructor field


    【解决方案1】:

    你应该把它改写为:

    class Foo(
        private val bar: Int,
        private val baz: Int, 
    ) {
        constructor(bar: String, baz: Int) : this(bar.toInt(), baz)
    }
    

    (Int, Int) 构造函数已成为主构造函数,初始化所有值。第二个构造函数委托主构造函数。

    您在非工作代码中声明的前两个辅助构造函数不能重新分配vals,因为它们委托给另一个构造函数,并且假定该构造函数初始化了所有必要的属性。虽然在这种情况下,它没有,所以你得到另一个错误。

    【讨论】:

    • 这是有道理的。所以总结一下:使用首选类型的字段创建一个主构造函数,并添加辅助构造函数,其目的是将替代数据类型转换为字段的类型。我认为这是一种很好的看待它的方式。谢谢!
    • @humleflue 是的,完全正确。辅助构造函数类似于“便利”构造函数。 (这正是斯威夫特所说的:D)
    • 辅助构造函数的替代方法是伴随对象中的工厂方法。如果你将它定义为operator fun invoke(…),那么调用它看起来就像一个构造函数调用——但它可以在调用真正的构造函数之前做尽可能多的处理,它也可以返回一个缓存的对象,子类实例等 (主要缺点是子类构造函数不能调用它。)
    【解决方案2】:

    这行不通,因为您的私有构造函数无法初始化所有属性。你把它当作一个简单的函数调用。

    为什么不这样做?

    class Foo {
        private val bar: Int
        private val baz: Int
    
        constructor(bar: Int, baz: Int) { 
            this.bar = bar
            this.baz = baz
        }
    
        constructor(bar: String, baz: Int) : this(bar.toInt(), baz) 
    }
    

    【讨论】:

    • 或者正如其他答案所示,可以将第一个构造函数提升为主构造函数以简化它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-26
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    相关资源
    最近更新 更多