cypher121
06/02/2019, 8:33 AMfun <E : Enum<E>> foo(clazz: Class<E>): Value<E> = TODO()
fun <T> bar(clazz: Class<T>) {
if (Enum::class.java.isAssignableFrom(clazz)) {
foo(clazz) //fails since T is not Enum<T>
}
}
how do I call foo here? I tried foo<Enum<*>>(clazz as Class<Enum<*>>)
but it fails since * is also not Enum<*> and it just keeps going recursively. In java I'd just use a raw Enum type, but I can't do that hereDico
06/02/2019, 11:14 AMclazz as Class<Enum<T>>
?cypher121
06/02/2019, 11:22 AMMarc Knaup
06/02/2019, 11:37 AMfun <T> bar(clazz: Class<T>) {
if (Enum::class.java.isAssignableFrom(clazz)) {
foo(clazz as Class<Nothing>)
}
}
Nothing
is a (theoretical) subclass of every type.cypher121
06/02/2019, 12:09 PMfun <E : Enum<E>> foo(a: () -> E) = a()
fun <T> bar(b: () -> T): T {
return foo(b as (() -> Nothing))
}
bar will actually throw an exception since it assumes foo can never actually return a value, so it replaces the return with throw null
Marc Knaup
06/02/2019, 12:16 PMNothing
if you're uncertain.
In your initial bar
function you've lost some generic type information. You cannot get around an unsafe cast in that situation.
if you want to have a safe cast, use T: Enum<T>
in bar
- but that makes Enum::class.java.isAssignableFrom
unnecessary and is probably not your use case.cypher121
06/02/2019, 12:19 PMMarc Knaup
06/02/2019, 12:25 PMNothing
value is actually used at the generic site)
• cast to another type which fulfills the same recursive constraint
The latter should not cause any issues because at runtime it's all Any
anyway.streetsofboston
06/02/2019, 12:56 PM... but make sure that noThankfully, that is super easy: There are no values of typevalue is used ...Nothing
Nothing
. It's impossible to use/create/receive one.Marc Knaup
06/02/2019, 12:58 PMtDnamein
06/02/2019, 9:01 PMstreetsofboston
06/02/2019, 10:25 PM