Lets say I have this ```class Preference<T : An...
# announcements
j
Lets say I have this
Copy code
class Preference<T : Any> private constructor(
        val key: String,
        val default: T,
        val type: KClass<T>
)

// Extension Function
fun getPref(): T { // This should be a nullable generic set by the preference
    // parse and return pref
}
Now, not every preference is not-null. So how can I omit
<T: Any>
to get to
<T>
so the preference itself can set itself nullable only via its type generic? The problem is that KClass does not like <T> and requires <T: Any> is there any smart way to get a not-null type generic from a nullable one? Or a reified function way to handle that?
m
Isn't this just what you mean?
Copy code
class Preference<T : Any> private constructor (
        val key: String,
        val default: T?,
        val type: KClass<T>
    )
l
If getPref will never return null, it’s ok the way you have it
j
No, then I would have to make getPref() nullable for every preference. I want to let the Pref itself decide if its nullable
Copy code
val notNull: Preference<String>...
val nullablle: Preference<String?>...
so basically T, which is defined here above should be used in getPref to decide whether the preference is nullable or notnull
Well I want getPref to be nullable for some prefs
l
you can declare the same function and just make one nullable
j
that would not let the Preference type decide if its nullable, but the caller site
l
but you will have trouble importing this. It will have to take one and it will not check first if it’s null and then decide for you which one
I would do one function that checks for the nullability of T
if it’s null you call a private function getPrefNull and if it’s not null you call a private function getPrefNotNull
j
that wouldnt solve compiler warnings etc
l
Assuming both return the same stuff
j
the compiler would still yell at you "nullable"
Copy code
fun doThis(): T? = ...
fun doThat(): T = ...
DecideThisThat would now have to return a nullable type
Copy code
fun decideThisThat(): T? = if (nullable) doThis() else doThat()
l
what will you return if T is null?
j
Copy code
class Preference<T> private constructor(
        val key: String,
        val default: T,
        val type: KClass<T!>
)
// Extension Function
fun getPref(): T { // This should be a nullable generic set by the preference
    // parse and return pref
}
Basically this is what i want: • T is nullable and default is nullable • getPref now uses null-safe type generics (nullable if T of pref is nullable) • KClass doesnt cry about a nullable generic Problem: you cant just make T!
I think i could just make KClass<T> KClass<*>, but i want that type safety
m
you can't have a constructor accepting both a nullable and non-nullable type and then define a function that only returns the non-nullable type. You simply don't know whether the value within preference is nullable or not. And since returning T? encapsulates T you have to go for T? on the getPref() function
j
hm not really, no
Copy code
class Data<T>(val data: T)

fun <T> Data<T>.get(): T = data

fun main() {
    val example = Data<String?>("Hello")
    example.data
    val example2 = Data("Hello")
    example2.data
}
example.get()
is nullable,
example2.get()
is not null the nullability is defined by the type generic in the constructor
It is a very complex problem, I know
so the problem is KClass does not like nullable T, it wants T: Any and I do not want to erase that type generic there since it will break stuff
k
There isn't a way to do this, it's something that bothers me too
c
IMHO you always can create the NullablePreference and Preference, both having the method you want, and create a Factory if you want to hide the 2 classes. If it needs to be an extension function because you can't change Preference.... Isn't possible to do: Preference<T>.getPref() : T Preference<T?>.getPref(): T?