VolodymyrH
VolodymyrH

Reputation: 2019

What is the better way to declare fields in data class in Kotlin?

Say I have a data class:

data class Money(private var _amount: Int, private val currency: String) {
    private var amount: Int = _amount
        get() {
            return if (field < 0) 0 else field
        }

    override fun toString(): String {
        return "Money(amount=$amount, currency='$currency')"
    }

}

I want to know what should I pass as a parameter: var or val? Should I add private modification? In which case is the best practice? Because when I add a getter I must change it to var, but as I know, it's always better to write val in Kotlin?

Upvotes: 2

Views: 3516

Answers (1)

ice1000
ice1000

Reputation: 6569

I'd like to write the code you've given like this:

data class Money(private var _amount: Int, private val currency: String) {
    private var amount: Int
        get() = _amount.coerceAtLeast(0)
        set (value) { _amount = value }

    override fun toString() = "Money(amount=$amount, currency='$currency')"
}
  • _amount can be simply a parameter, it shouldn't be a field, it will gone after construction, and it's only accessible in the init block, the constructor and the field variable initializers (imagine a constructor parameter in Java).
  • coerceAtLeast is a useful utility extension in the stdlib
  • methods with only one return statements can be written as one-linear
  • Data classes should be pure data classes, I don't think you should declare a property with backing field.
    • Instead, use a private property as the backing field and mutate the backing field through the getter and the setter which are actually wrappers to the private field.

A less important thing is, the type of amount can be inferred, but I'd like to explicitly declare it here since it's more friendly for new comers to read.

Upvotes: 2

Related Questions