Oliver.O
08/18/2021, 9:07 PMget()
• get<DateModel>()
Currently, it requires two function definitions to achieve the goal, which might be resolved by introducing a default type for a type parameter as shown in the following example:
package genericMethodDefaultType
open class Model
open class AttributeModel : Model()
data class DateModel(var value: String) : AttributeModel()
val modelCache = mutableMapOf<Int, Model>()
@Suppress("UNCHECKED_CAST")
class ModelReference<SpecificModel : Model>(private val modelId: Int) {
// Variant (1) returning the default type.
fun get() = modelCache[modelId]!! as SpecificModel
// Variant (2) returning a derivative.
@JvmName("getSpecific") // required to disambiguate JVM signatures
fun <MoreSpecificModel : SpecificModel> get() = modelCache[modelId]!! as MoreSpecificModel
// Variant (3) replacing (1) and (2) – currently not valid Kotlin:
// fun <MoreSpecificModel = SpecificModel : SpecificModel> get() = modelCache[modelId]!! as MoreSpecificModel
//
// Note the specification of a default type ` = SpecificModel` which shall be used if type inference cannot
// determine a result.
}
@Suppress("UNUSED_VARIABLE")
fun main() {
val modelId = 42
modelCache[modelId] = DateModel("2021-08-18")
val attributeModelReference = ModelReference<AttributeModel>(modelId)
// Some code would access attribute models like this:
val attributeModel1 = attributeModelReference.get()
// Does not compile if `get()` variant (1) is not defined: Not enough information to infer type variable MoreSpecificModel
// If `get()` variant (1) is not defined, we would have to specify the type redundantly like this:
val attributeModel2 = attributeModelReference.get<AttributeModel>()
// A date view might want to access its model like this:
val dateModel = attributeModelReference.get<DateModel>()
println(attributeModel1)
println(attributeModel2)
println(dateModel)
}
Is this too exotic or do there exist better solutions for the above case?elizarov
08/19/2021, 10:42 AMOliver.O
08/19/2021, 10:46 AMelizarov
08/19/2021, 10:48 AMOliver.O
08/19/2021, 10:51 AMgeneric
prefix for the function returning the more generic type. I still prefer the above variants (1) plus (2) as these allow invocations via the same name as if type inference was working as usual.