1
votes

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?

1
Make it mutable if you plan on mutating it. Otherwise make it immutable. If you aren't sure, and it is app code, start out with immutable and change it if you need to. If it is library code, think it over.Aluan Haddad

1 Answers

2
votes

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.