Getter for mutable collections

Last default encapsulation for mutables was something like:

private val _foo: MutableList<Int> = mutableListOf()
val foo: List<Int> = _foo

Here could be a simpler way with a single naming:

private val foo: MutableList<Int> = mutableListOf()
    public get () = field.toImmutableList()

Is it fine?

There is experimental compiler feature:

val foo: List<Int>
    field = mutableListOf()

See Explicit Backing Fields

2 Likes

Looks nice. Currently I’m trying to overpass it with

protected val foo: MutableList<Int> = mutableListOf()
fun getFoo(): List<Int> = foo

it works with a private but not with a protected foo because of same JVM signature error. Looks ok with internal visibility, there’s something wrong with Kotlin’s protected implementation.

There’s nothing wrong with it. Compiler can’t use automatic name mangling for items that could be accessed from outside of the module. You have to rename manually with @JvmName.

1 Like
val foo: List<Int>
    field = mutableListOf()

what if we need something like this? Is it included in proposed getter?

class A(){
  protected var foo: MutableList<Int>? = null
    val getFoo(): List<Int>? = foo
  }

class B: A() {
  init {
      foo = mutableListOf(if (true) 1 else 3) 
    // There we don't need to check if list was created or make it empty
  }
}

And is it even will be possible to add such getter on a constructor parameter?

Looking a little larger use case than a single variable, if this is part of a class where that variable is exposed via an interface you can simply do this:

interface A {
    val foo: List<Int>
}

class AImpl : A {
   override val foo = mutableListOf()
}

Tried interface but I also need something like encapsulation and setter here. So, I did it this way:

class Foo(private var type: Int): Bar(someParams = something), MyInterface {
  fun setType(value: Int) {
  //update dependencies
  //send reactive event to update UI
  }
}