Emil Kantis
05/17/2023, 10:32 PMephemient
05/18/2023, 3:11 AMinline class Foo<reified T>
but that can't work because you can't inline a class into its callsiteEmil Kantis
05/18/2023, 7:42 AMinline fun <reified T> stringSerializer(
crossinline decode: (String) -> T,
crossinline encode: (T) -> String = { it.toString() },
nameOverride: String? = null,
): KSerializer<T> = object : KSerializer<T> {
override val descriptor = PrimitiveSerialDescriptor(nameOverride ?: T::class.simpleName!!, PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder) =
decode(decoder.decodeString())
override fun serialize(encoder: Encoder, value: T) =
encoder.encodeString(encode(value))
}
This will then be used like:
object FooSerializer : KSerializer<Foo> by stringSerializer(Foo::FromString)
I think this is kind of hard for people from OO-land and that this would be an easier to entry for them:
abstract class StringSerializer<T>(
nameOverride: String? = null,
): KSerializer<T> {
override val descriptor = PrimitiveSerialDescriptor(nameOverride ?: T::class.simpleName!!, PrimitiveKind.STRING) // Cannot use T as reified here
abstract fun decode(value: String): T
abstract fun encode(value: T): String
override fun deserialize(decoder: Decoder) =
decode(decoder.decodeString())
override fun serialize(encoder: Encoder, value: T) =
encoder.encodeString(encode(value))
}
object FooSerializer : StringSerializer<Foo>() {
override fun decode() = TODO()
override fun encode() = TODO()
}
So I guess the template comparison makes sense, the inline class would always create specializations on use. I think it would be up to the compiler to generate these specializations during compile-timeephemient
05/18/2023, 8:34 AMinline fun <reified T> StringSerializer(...)
) would make its usage feel more OO?franztesca
05/18/2023, 4:34 PMfun <reified T> example() {
println(T::class)
}
fun main() {
example<Int>()
}
could be compiled to
fun example(clazz: KClass) {
println(clazz)
}
fun main(){
example(Int::class)
}
Which is what people end up doing manually right now with:
@PublishedApi
internal fun example(clazz: KClass<*>) {
println(clazz)
}
inline fun <reified T> example() = example(T::class)
Following the kotlin mantra, I would expect this boilerplate to be removed.ephemient
05/18/2023, 5:39 PMfranztesca
05/18/2023, 8:33 PMephemient
05/18/2023, 11:02 PMarrayOf<T>()
needs a reified type, not just a class reference
typeOf<T>()
exposes generic type parameters which are lost with a class reference