Search code examples
immutabilitykotlincircular-reference

Circular references with vals in Kotlin


In Kotlin, say I have data class A (val f: B) and data class B (val f: A). I want to initialize local var a: A and var b: B such that a.f is b and b.f is a. A.f and B.f must remain vals. Is this circular instantiation possible?

data class A(val f: B)

data class B(val f: A)

fun foo() {
    var a: A
    var b: B
    // instantiate a and b here with a.f == b and b.f == a ??
}

Solution

  • Not exactly what you want but should work:

    interface A {
      val f: B
    }
    
    interface B {
      val f: A
    }
    
    data class AImpl(override var f: B) : A
    
    data class BImpl(override var f: A) : B
    
    fun <T> uninitialized(): T = null as T
    
    fun foo() {
      var aImpl = AImpl(uninitialized())
      var bImpl = BImpl(aImpl)
      aImpl.f = bImpl
      val a: A = aImpl
      val b: B = bImpl
    }
    

    If you do not care about data class properties being vals, you can get rid of interfaces and use just implementation classes.