Reputation: 1734
I have a custom type declared as:
data class User (
val name: String,
val rank: Int
)
and wish to declare a Map whose keys are the name and values are the ranks, referring to the types as declared for User.
I have tried kotlin reflection,
val foo1 = Map <User::name, User::rank>() //compiler error 'not enough information to infer type...'
Is there a normative way to do this?
So far, I "just have to know" the types for key and value, e.g:
val foo = Map <String, Int>()
But this is brittle, and would break if I change User in the future, e.g .rank
from Int to Float. Of course, I wouldn't remain ignorant of my oversight for long, I expect the compiler would start complaining, but is there something elegant I can do now?
Upvotes: 0
Views: 266
Reputation: 7109
You could use a value class to define the user's name and rank.
@JvmInline
value class UserName(val name: String)
@JvmInline
value class UserRank(val rank: Int)
data class User (
val name: UserName,
val rank: UserRank,
)
val userMap = Map<UserName, UserRank>() // type-safe map
Or create a value class that implements Map<String, Int>
, and use delegation.
@JvmInline
value class UserMap(
private val map: Map<String, Int>
) : Map<String, Int> by map {
operator fun contains(user: User): Boolean =
map[user.name] == user.rank
}
Or both together!
Upvotes: 1