I'm relatively new to the Kotlin community and found this apparently simple error that I haven't been able to solve yet:
import com.akuleshov7.ktoml.Toml
import com.akuleshov7.ktoml.source.decodeFromStream
import java.io.File
import java.io.InputStream
class Something <out T> {
private val file = File("file.toml").inputStream()
private val content = Toml.decodeFromStream<T>(file)
}
Apparently Toml.decodeFromStream<T>(file)
cannot use the wildcard from the class or it will return the error Cannot use T as reified type parameter. Use a class instead
I kind of found a workaround by implementing this function:
private inline fun <reified R : T> call() {
// ...
}
Still that forces me to include the type when calling the function and even if it doesn't I still need to do this in the constructor. Has anyone found this error before?
I'm starting to think that what I want (Using the class wildcard in the method decodeFromStream
) might not be possible in the constructor, o I just want to know if it's indeed not possible or, if it is, what should I change?
If syntax is important to you, you can spoof a constructor with the invoke()
operator function, and use the method that @broot mentioned in his comment to get something like this. I've added a path
constructor parameter because I'm not sure what the actual means of instantiating the inputStream
is.
This will give you an unchecked cast
warning but should work. Example uses JSON.
@OptIn(ExperimentalSerializationApi::class)
class Something<out T> @PublishedApi internal constructor(path: Path, clazz: Class<T>) {
private val file = path.inputStream()
private val content = Json.decodeFromStream(Json.serializersModule.serializer(clazz) as KSerializer<T>, file)
companion object {
inline operator fun <reified T> invoke(path: Path): Something<T> {
return Something(path, T::class.java)
}
}
}
val test = Something<MySerializableClass>("path/to/file.json")