Hi! Is it possible to implement an interface by delegation in a value class? This doesn’t work: ```i...
j
Hi! Is it possible to implement an interface by delegation in a value class? This doesn’t work:
Copy code
interface I

@JvmInline
value class A(val instance: I) : I by instance // Error: Value class cannot implement an interface by delegation if expression is not a parameter
and I’m wondering whether value classes lack that feature or I’m the one missing something here
j
The main goal is to avoid object creation. In this case, its not useful to use delegation, value class must have one argument, that will be replaced by its type, ex.:
Copy code
value class Age (value: Int)
val age = Age(10)
At compile time will be replaced by
val age: Int = 10
j
@Jhonatan Sabadi thanks for looking into this. I’m still a little bit confused, though. The main goal is to avoid unnecessary object creation. Could you explain why it is not useful to use delegation in this case? Afaik the delegated interface implementation doesn’t do more than just tell the compiler to generate default code. So it shouldn’t matter if I write
Copy code
interface I {
    fun foo()
}

@JvmInline
value class A(val instance: I) : I by instance
or
Copy code
interface I {
    fun foo()
}

@JvmInline
value class A(val instance: I) : I {
    override fun foo() {
        instance.foo()
    }
}
The goal here is to ensure on the type level a “deeper meaning” of some
I
instances but also not to lose the perks of the
I
interface, and the last time I checked it seems to work as expected, the underlying
instance
doesn’t get boxed when
foo
is called on
A
.
j
value class takes a parameter of primitive type, like String, Int, Float and so on. In this case, you could use a simple class, does not need to use a value class, or declare your I interface with more meaningful name
j
Well, that’s not exactly true. A value class can take a parameter of whatever type you want.
String
is not a primitive type on JVM, also take a look at the
Result
implementation, please. It’s inline and takes
Any?
as the parameter.
In case anyone bumps into this thread looking for an answer: Indeed, there used to be such a limitation, but as of Kotlin 1.7 it should be no more.