Calling implementation method in extension function with same name


#1

I’m playing with kotlin and trying to do something similar like in swift.
Basically having huge json parsed into map of maps of maps… and i’d like to do

myobject["key1"]["key2"]["key3"]

so i made simple operator function as extension function

private operator fun Any?.get(key: String): Any? = (this as? Map<*, *>).get(key)

problem is that the .get(key) is calling recursively itself so ending in infinite loop,

I workaround it by defining another extension function out of the scope which works, but wondering if i can call something like super.get(key) in case of inheritance to call concrete type implementation function directly (not again my extension function)


Following works, but of course not so nice

private fun Map<*,*>?._get(key: String) = (this as Map<*,*>)?.get(key)

class SomeClass(private val data: Map<String, Any>) {

    private operator fun Any?.get(key: String): Any? = (this as? Map<*, *>)._get(key)

    fun measureConfig(key: String): Map<String, *> {
        return myobject["key1"]["key2"]["key3"]
    }
}

Any ideas ?

Thank you


#2

I haven’t tried it, but there is one key problem with this code which will certainly stop it from calling .get on Map. Map<*,*>? is not the same as Map<*, *> or (even more correct) Map<String, *>. Try:

private operator fun Any?.get(key: String): Any? = (this as? Map&lt;String, *&gt;)?.get(key) ?: throw IllegalArgumentException("Not a map")

The throw is just a “safety feature”, depending on your use case you could consider null a valid return value and not have the throw bit.


#3

Hi,

ty for reply.
I understand the typing issue, that’s not my concern though.
This is for learning purpose.
Anyway i found nicer solution… as we have import as I can make an alias

import kotlin.collections.get as mapGet

class SomeClass(private val data: Map<String, Any>) {

    private operator fun Any?.get(key: String): Any? = (this as? Map<*, *>).mapGet(key)

    fun measureConfig(key: String): Map<String, *> {
        return myobject["key1"]["key2"]["key3"]
    }
}

It’s not exactly what I was looking for, but definitely better…