how to use this function Map.getValue( thisRef: Any?, property: KProperty<*>)

Viewed 128

I see this function on kotlinlang.org, but i don't know how to use it.

operator fun <V, V1 : V> Map<in String, V>.getValue(
    thisRef: Any?,
    property: KProperty<*>
): V1

For example, I have this map: val map = mapOf("one" to 1). How do you get 1 with this getValue function?

UPDATE:

Is there any way that you can get it to work with val anotherMap = mapOf(1 to 1). Now the key is an Int. I've changed Map to Map<in Int, V>, but it won't work.

3 Answers

The getValue operator function is declared on Map, so that Map can be used as a property delegate.

Note that the first parameter thisRef is ignored by the implementation. It is only included so that the function signature matches the signature required for a property delegate.

You will not normally call this function directly yourself. A call to getValue would be generated automatically when you use a Map as a property delegate, as part of the implementation of the property's setter.

What it does is rather straightforward - it accesses the map using the property name as key. See the code here.

Here is an example usage:

class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int     by map
}

fun main() {
    val user = User(mapOf(
        "name" to "Sweeper", "age" to 42
    ))
    println(user.name) // prints Sweeper
}

In the setter for name, for example, the generated call to getValue would look something like:

map.getValue(this, this::name)

See also the "storing properties in a map" section.

As mentioned in Indexed access operator you can just call

val value = map["one"]

to read the value 1. But this doesn't call your special getValue function. You missed the function body to see what getValue it does. Here is an example for calling your method:

operator fun <V, V1 : V> Map<in String, V>.getValue(
    thisRef: Any?,
    property: KProperty<*>
): V1  = this[property.name] as V1

val map = mapOf("one" to 1)

data class Pojo(val one: String)

val pojo = Pojo("one")
val valueByProp : Int = map.getValue(map, Pojo::one)

The documentation explains how to retrieve values data from Maps.

https://kotlinlang.org/docs/map-operations.html#retrieve-keys-and-values

For retrieving a value from a map, you must provide its key as an argument of the get() function. The shorthand [key] syntax is also supported. If the given key is not found, it returns null. There is also the function getValue() which has slightly different behavior: it throws an exception if the key is not found in the map.

val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.get("one"))
println(numbersMap["one"])
println(numbersMap.getOrDefault("four", 10))
println(numbersMap["five"])       // null
//numbersMap.getValue("six")      // exception!

Typically getValue() is used when using a Map with a default. See https://youtrack.jetbrains.com/issue/KT-11851

Related