TL;DR
for any class with component functions, allow using spread operator(*) to extract is fields, namely:
data class Class0(val a:Int,val b:Int)
fun useInts(a:Int,b:Int)=...
val instance0=Class0(0,0)
useInts(instance0.a,instance0.b) // current approach
useInts(*instance0) // desired approach
I’m writing a program that needs to transfer data(class1) using udp, and store it with some additional information(class2) in memory, let’s say:
data class Class1(val a:Int,val b:Int,val e:Int) // have fewer fields so it's smaller on wire
data class Class2(val a:Int,val b:Int,val c:Int,val d:Int) // extra fields records additional data
fun checkAndBuildClass2(a:Int,b:Int,e:Int):Class2{
if(e!=0)...
return Class2(a,b,info1(...),info2(...))
}
val c1=readClass1(...)
val c2=Class2(c1.a,c1.b,info1(c1),info2(c1)) // current approach
val c3=Class2(*c1,0) // desired approach if we wanna use c1.e as c2.c
val c4=checkAndBuildClass2(*c1) // desired approach if we have a primitive function
since data class forbids inheritance, I can’t let class2 extends class1
I can write Class2(val ref:Class1,val c:Int,val d:Int) but it introduces a pointer dereference, and requires users of class2 to know about class1
also I if don’t need class1.e, I can’t remove it in both approaches
in this example, only field a and b is shared, but in reality, there could be dozens of fields
yes, class1 and class2 are related, and because they’re data classes, they can’t inherit
introducing a interface automatically would solve the problem rather elegantly(see related link)
what I’m suggesting here is that there should be a way to take advantage the fact that class have components
are there other ways that one won’t have to repeatedly type instance name and their field names for related class?
and I’ve edited the post, changing the signature of useInts(…) because the original one is misleading
I meant to illustrate the usage of destructive method call but instead I give a poor example
Just wanted to point out that Kotlin has inline extension methods like with, apply, and run that could eliminate the need to repeat the variable, so instead of:
useInts(instance0.a,instance0.b) // current approach
You could do one of the following depending on the situation:
with(instance0) { useInts(a, b) }
instance0.run { useInts(a, b) }
instance0.apply { useInts(a, b) }
with and run are equivalent and the result of the expression is the return value of useInts. apply will have a result of instance0.
There is also let and also that are like run and apply but take the value as a parameter so you could do:
thx for the intel. I’m aware of this so I originally wrote
this way we can’t just use a or b because of naming collision
even for the simple case, we have to repeat a and b and every other field
on second thought, my approach is not a perfect one because it only solves part(but not all) of the problem
the tuple interface seems a good way to go, hope that one got implemented soon