Michael de Kaste
04/07/2020, 9:28 AMinterface Code{
private val code: String
}
interface Keyable{
private val key: String
}
fun <T> getThing(obj: T) : Pair<String, String?> where T : Code, T maybe Keyable{
return obj.code to obj.key //implied that since we're not sure that Keyable is implemented, the field becomes nullable
}
diesieben07
04/07/2020, 9:30 AM(obj as? Keyable)?.key
.Michael de Kaste
04/07/2020, 9:31 AMdiesieben07
04/07/2020, 9:31 AMStephan Schroeder
04/07/2020, 9:32 AMgetThing
methods, once that takes a Keyable
and one (probably slightly different named) that takes another object. As Kotlin is a statically compiled language, the interfaces of your object need to be known at compile-time not run-time.diesieben07
04/07/2020, 9:32 AMMichael de Kaste
04/07/2020, 9:34 AMStephan Schroeder
04/07/2020, 9:34 AMfun <T:Code> getThing(obj: T) : Pair<String, String?> {
if(T is Keyable) {
return obj.code to obj.key //implied that since we're not sure that Keyable is implemented, the field becomes nullable
}else {
return ...whatever you do if it isn't Keyable
}
}
There is even smartcasting.diesieben07
04/07/2020, 9:35 AMval keyable = obj as? Keyable
// more logic
keyable?.thing
...
keyable?.otherThing
Stephan Schroeder
04/07/2020, 9:36 AMas
throws an Exception if the object isnāt of that class, use is
!diesieben07
04/07/2020, 9:37 AMas
, as?
diesieben07
04/07/2020, 9:37 AMas?
returns null if the cast is not possibleStephan Schroeder
04/07/2020, 9:38 AMas?
just means the type can be nullable, itāll still throw that exception if your object isnāt of that type or null. Use is
šdiesieben07
04/07/2020, 9:38 AMdiesieben07
04/07/2020, 9:38 AM"foo" as? Int
is nulldiesieben07
04/07/2020, 9:38 AM"foo" as Int?
(what you mean) throws exceptionMichael de Kaste
04/07/2020, 9:38 AMdiesieben07
04/07/2020, 9:38 AMStephan Schroeder
04/07/2020, 9:39 AMis
is the safe cast! but only within the true-case if-block!diesieben07
04/07/2020, 9:39 AMMichael de Kaste
04/07/2020, 9:40 AMreturn when(it){
is Int -> it //as Int smartcast
else -> null
}
diesieben07
04/07/2020, 9:40 AMStephan Schroeder
04/07/2020, 9:40 AMas
the āunsafe castā https://kotlinlang.org/docs/reference/typecasts.html#unsafe-cast-operatordiesieben07
04/07/2020, 9:40 AMdiesieben07
04/07/2020, 9:40 AMStephan Schroeder
04/07/2020, 9:41 AMis
is the one to use here.diesieben07
04/07/2020, 9:41 AMdiesieben07
04/07/2020, 9:41 AMnull
, which is what was originally requested.Stephan Schroeder
04/07/2020, 9:42 AMStephan Schroeder
04/07/2020, 9:42 AMdiesieben07
04/07/2020, 9:43 AMas?
, and it can be very useful.
For example:
val something = (obj as? Foo)?.key ?: "default value"
diesieben07
04/07/2020, 9:43 AMis
is much more verboseStephan Schroeder
04/07/2020, 9:45 AMas?
works but otherwise Iād still go for
val something = if(obj is Fee) obj.key else "default value"
diesieben07
04/07/2020, 9:45 AMMichael de Kaste
04/07/2020, 9:46 AM(obj as? Fee).key ?: "default value"
I'm not a fan of onelining an if like that. But mostly because the ternary operator got wrongfully omitted from design (personal opinion)Stephan Schroeder
04/07/2020, 9:47 AMreturn obj.code to (obj as? Keyable)?.key
is shortest here and the way to go.