Search code examples
listkotlingenericsdata-classgeneric-function

Create generic extension to make a deep copy of a List with Data Class


Hi I'm trying to create a generic function to make a deep copy of list using the copy() method that a Data class provide us.

I'm using the method that I found on other post which returns a list of objects being deep copied:

listDataClass.map{ it.copy() }

But I can't seem to know how to make it as a generic function for data class so I'm really curious to see how'd you make one like this.


Solution

  • By using kotlin reflection magic, you can do it like this:

    class NotADataClassException(clazz: KClass<out Any>): Exception("$clazz is not a data class")
    
    fun List<T>.deepCopy(): List<T> {
        return map { item ->
            if (!item::class.isData) {
                throw NotADataClassException(item::class)
            } else {
                item::class.members.first { it.name == "copy" }.callBy(emptyMap()) as T
            } 
        }
    }
    

    However, this is bad because of the following reasons:

    • This doesn't constrain the elements to data classes at compile time (that is what we wanted to do with the generics!) instead, it throws an exception.

    • Kotlin reflection is slow and big, and reflection is used for every item.