https://kotlinlang.org logo
#getting-started
Title
# getting-started
p

Paul Griffith

09/20/2021, 6:08 PM
Is there a way to have a data class secondary constructor provide a value for a non-primary-constructor
val
? 🧵 ->
I want to have a
val
member of the class that is, if you call the primary data class constructor, null, or if you use the secondary constructor, whatever you supplied. I do not want this field to be in equals/hashcode...but I also don't really want to write my own equals & hashcode, and this seems reasonable (albeit an edge case)
This is the 'best' workaround I can come up with, by using a secondary property
j

Joffrey

09/20/2021, 6:39 PM
Why don't you just remove the secondary constructor, and provide
deferredType
with
null
default value in the primary constructor?
Copy code
data class Attribute constructor(
        override val name: String,
        override val location: String,
        override val description: String? = null,
        override val kind: Kind = Kind.INSTANCE_MEMBER,
        private val deferredType: TypeSupplier? = null,
) : CompletionDescriptor()
p

Paul Griffith

09/20/2021, 6:40 PM
It'll still be used in the autogenerated`equals` and
hashcode
in that case, and
TypeSupplier
is a SAM with no meaningful equals/hashcode implementation
Some kind of
@Omit
annotation would be ideal but searching this Slack makes it seem like the official suggestion is just to override equals & hashcode yourself
j

Joffrey

09/20/2021, 6:41 PM
Good point, in that case your solution seems appropriate, nothing comes to mind at the moment
👍 1
p

Paul Griffith

09/20/2021, 6:41 PM
Which is fair, like I said, this is an edge case
j

Joffrey

09/20/2021, 7:32 PM
Oh wait I just realized you could simply make the setter private for `deferredType`:
Copy code
data class Attribute constructor(
        override val name: String,
        override val location: String,
        override val description: String? = null,
        override val kind: Kind = Kind.INSTANCE_MEMBER,
    ) : CompletionDescriptor() {
        override var deferredType: TypeSupplier? = null
            private set

        constructor(
            name: String,
            location: String,
            description: String? = null,
            kind: Kind = Kind.INSTANCE_MEMBER,
            deferredType: TypeSupplier? = null,
        ) : this(
            name, location, description, kind
        ) {
            this.deferredType = deferredType
        }
}
1
p

Paul Griffith

09/20/2021, 8:03 PM
That's elegant enough for me, good stuff
4 Views