Why can’t `this` be passed to an interface delegat...
# announcements
s
Why can’t
this
be passed to an interface delegate when initializing the delegate?
Copy code
data class Foo(
    val name: String
): FooExt by FooExtImpl(this)

interface FooExt {
    fun nameExt(): String
}

class FooExtImpl(private val outer: Foo): FooExt {
    override fun nameExt() = "Hello, ${outer.name}"
}
I basically need this exact functionality, I’m not able to directly add
nameExt
to the data class. If delegates could be initialized inside an
init { }
block then that would work but I’m unsure of any actual workarounds for this.
z
Because
this
doesn’t exist when you’re creating the delegate – kotlin needs the delegate in order to create the class, so it’s a chicken/egg problem. Even if you were able to access an uninitialized version of the delegating class, it would be really hard to reason about initialization order. This issue already exists with superclasses accessing open members, since they might not be initialized when the superclass constructor runs, and Kotlin will give you warnings about this I believe.
s
That’s not how I understood delegation to work. I assumed the compiler just synthesized the initialization of the delegate by copying it into the constructor. I could do this easily by hand. Consider the equivalent:
Copy code
data class Foo(val name: String): FooExt {
  private val delegate: FooExtImpl(this)
  
  override fun nameExt() = delegate.nameExt()
}
In fairness I should take a look at the generated bytecode.
z
Yea, it would be possible. Given the confusion that usually results from the superclass issue though, I’m guessing they just didn’t want to add another case where there was implicit ordering and easy to introduce bugs.
At least one JetBrains person has said that implementation-by-delegation is the one kotlin feature they wish had never been built, because it adds so many weird edge cases or something. So they might just be trying to keep those from exploding.
d
Don't delegate 😉
z
Yes, everyone knows inheritance is the better pattern anyway 😉
😁 1
s
I don’t see how inheritance would help here since you still can’t initialize the superclass from the constructor which is what we’re looking to do here… In general though I do agree