Search code examples
kotlinconstantsimmutability

How to create immutable objects in Kotlin?


Kotlin has a const-keyword. But I don't think constants in kotlin are what I think they are. It seems to very different to const in C++. It seems to me that its is only available for static members and to what are primitives in Java and do not compile for class-variables:

data class User(val name: String, val id: Int)

fun getUser(): User { return User("Alex", 1) }

fun main(args: Array<String>) {
    const val user = getUser()  // does not compile
    println("name = ${user.name}, id = ${user.id}")
    // or
    const val (name, id) = getUser()   // does not compile either
    println("name = $name, id = $id")
}

As this seems not to work, I think what i really want is a second class, that deletes the operations i don't want to support:

class ConstUser : User
{
    ConstUser(var name: String, val id: int) : base(name, id)
    { }
    /// Somehow delte the setters here?
}

The obvious downside to such a apprach is that I must not forget to change this class, in case i change User, something that looks very dangerous to me.

But I'm not sure how to do this. So the question is: How does one make immutable objects in ideomatic Kotlin?


Solution

  • The const modifier in Kotlin is used for compile-time constants. Immutability is done with a val keyword.

    Kotlin has two types of properties: read-only val and mutable var. vals are equivalent to Java's finals (I don't know how this relates to const in C++, though) and properties or variables declared as such can't change their values once set:

    data class User(val name: String, val id: Int)
    
    val user = User("Alex", 1)
    
    user.name = "John" // won't compile, `val` cannot be reassigned
    user = User("John", 2) // won't compile, `val` cannot be reassigned
    

    You don't have to hide or delete somehow any setters of val properties as such properties don't have setters.