For example i have serelization code:
inline fun<reified T : Any?> getSerializer() : Buffer.(T) -> Buffer
{
val clazz = T::class.java
val type = typeOf<T>()
return when
{
clazz == Integer::class.java -> Buffer::writeInt as (Buffer, Any?) -> Buffer
clazz == Long::class.java -> Buffer::writeLong as (Buffer, Any?) -> Buffer
clazz == Double::class.java -> Buffer::writeDouble as (Buffer, Any?) -> Buffer
clazz == Float::class.java -> Buffer::writeFloat as (Buffer, Any?) -> Buffer
clazz == String::class.java -> Buffer::writeString as (Buffer, Any?) -> Buffer
type is WildcardType && clazz == Map.Entry::class.java -> getMapEntrySerializer(type)
type is WildcardType && clazz == Collection::class.java -> getCollectionSerializer(type)
type is WildcardType -> throw IllegalArgumentException()
else -> getAllRegisteredSerializers()[clazz]
?: throw IllegalArgumentException("Try to get serializer for unregistered class $clazz")
}
}
I have to match class and type of T
. The second is what I have to make casts(smart cast does not work).
Why not make something like:
inline fun<reified T : Any?> getSerializer() : Buffer.(T) -> Buffer
{
val clazz = T::class.java
return when(T)
{
Integer -> Buffer::writeInt
Int -> Buffer::writeInt
Long -> Buffer::writeLong
Double -> Buffer::writeDouble
Float -> Buffer::writeFloat
String -> Buffer::writeString
Map.Entry(keyType, valueType) -> getMapEntrySerializer(keyType, valueType)
Collection(valueType) -> getCollectionSerializer(valueType)
else -> getAllRegisteredSerializers()[clazz]
?: throw IllegalArgumentException("Try to get serializer for unregistered class $clazz ")
}
}
KType class provides STAR
instance, so if generic type in unknown it won’t be broken.
This feature makes code pretty and understandable.