Exposing a Mutable member as Immutable


#1

While learning some Android, I came across an interesting scenario that has an official solution, but seems a bit verbose for Kotlin (but still more concise than Java).Consider the following scenario:

There is a controller type class which is responsible for keeping a current set of data. That set of data may change depending on the state of the model. Other classes may need to access that data, but we don’t want them to edit it. Consider the following code as an example:

class ImmutableAccessExample{ 
 
    private val theThingToBeEditedInternally = mutableListOf<String>()
 
    fun theThingToBeAccessedPublicly(): List<String> = theThingToBeEditedInternally
 
    init { 
        theThingToBeEditedInternally.add(0, "something") 
    } 
 
} 

According to official guidelines, the correct implementation would be something like this:

class ImmutableAccessExample{ 
     
        private val _theThing = mutableListOf<String>()
     
        val theThing: List<String>
                get()=_theThing
     
        init { 
           _theThing.add(0, "something") 
        }   
    } 

Is there a less verbose way to do this in Kotlin? My initial thought was something along the lines of this:

val theThing = mutableListOf<String>
    get()=this as List<String>

Obviously, there is a mismatch in the expected return type, and I’m not sure how the compiler would know when to refer to the MutableList since the get() is a List.

Original Context (Android ViewModel)

Regards


#2

In your particular case: private val, the official guideline is a bit more verbose than is needed. As the private val can never change, it only needs to be retrieved once instead of on every access of theThing:

val theThing: List<String> = _theThing

But there is nothing less verbose in Kotlin at the moment. It could not get much shorter anyway, because you have to define an additional “getter” with a different return type. This requires an indication that it is an additional getter, a name for the getter and the type the getter will return.

The shortest I could come up with is this. As you can see this only saves the initializer compared to the code above:

private val _theThing = mutableListOf<String>()
   get theThing: List<String>

I would expect an actual syntax for an additional getter to be a bit more verbose than this minimal example, so the savings would be even less or non-existent.


#3

Thanks for the reply. I’ll continue to use the documentation’s suggestions. I won’t expose the MutableLists because I can still call .MutableList.put on the member. It really isn’t a big deal now that you mention it. Perhaps Kotlin has lulled me into a state of unreasonably high expectations :slight_smile: