twisterrob
08/14/2018, 7:58 PM.let<Type> { }
val something: X
fun f() {
if (something is Y) {
(something as Y).g()
}
}
I see two options:
val something: X
fun f() {
val cacheOfSomething = something
if (cacheOfSomething is Y) {
(cacheOfSomething as Y).g()
}
}
or
(something as? Y)?.g()
neither of which is pleasing, any other way to do this?adam-mcneilly
08/14/2018, 7:59 PM(something is Y)
you should be able to smartcast inside of that block, no?dknapp
08/14/2018, 7:59 PMadam-mcneilly
08/14/2018, 7:59 PMif (thing is String) { println(thing.length) }
twisterrob
08/14/2018, 8:34 PMas Y
is not showing as redundantadam-mcneilly
08/14/2018, 8:35 PM(something as? MyClass)?.let { ... }
which would work in your example I believetrevjones
08/14/2018, 9:35 PMsomething.takeIf { it is Y }?.let { it.g() }
adam-mcneilly
08/14/2018, 9:36 PM(something as? Y)?.g()
wasn't preferable to you?
I think it's the most idiomatic way to accomplish what you're trying to do.trevjones
08/14/2018, 9:42 PMsomething.takeIf { it is Y }?.g()
is
is that the ide can tell you the check for instance is always true/false.twisterrob
08/14/2018, 10:14 PMtakeIf
, but I'm trying to call Y.g()
, not X.g()
😞 (takeIf
is not aware of cast)
@adam-mcneilly it introduces null to the mix, even though there's nothing nullable going on in the expression, it's just a simple non-null typecheck+cast.trevjones
08/14/2018, 10:18 PMinline fun <reified T, R: Any> Any?.takeAs(crossinline block: (T) -> R?): R? {
return if (T::class.java.isInstance(this)) block(this as T) else null
}
something.takeAs<Y> { it.g() }
twisterrob
08/14/2018, 10:24 PMinline fun <reified T> Any.run(crossinline block: T.() -> Unit) {
if (this is T) { block(this) }
}
note: you can do this is T
on reified no need for explicit reflection.trevjones
08/14/2018, 10:25 PMisInstance
because I can hit F1 on it and get a spew of documentation