I am trying to reduce code repetition by using a private constructor to assign a class field, but this does not seem to be possible.
What I'm trying to do is the exemplified here:
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
}
}
The alternative, that works, but which I am not satisfied with is doing the following:
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
}
}
To be clear I am not satisfied because of the replication of the this.baz assignment.
Is this simply not possible in Kotlin, or am I missing something?
CodePudding user response:
You should rewrite this as:
class Foo(
private val bar: Int,
private val baz: Int,
) {
constructor(bar: String, baz: Int) : this(bar.toInt(), baz)
}
The (Int, Int) constructor has been made into a primary constructor, initialising all the values. And the second constructor delegates the primary constructor.
The first two secondary constructors that you declared in your non-working code cannot reassign the vals, because they delegate to another constructor, and it is assumed that that constructor initialises all the necessary properties. Though in this case, it doesn't, so you get another error.
CodePudding user response:
That can't work because your private constructor fails to initialize all properties. You're treating it like a simple function call.
Why not do this?
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)
}
