christoph.pickl
02/02/2018, 5:19 AMdata class Person(
val name: String?,
val age: Int?
)
fun moduleExternal() = Person("", 1)
and a target function with a signature of:
fun safeCall(x1: String, x2: Int) {}
the following WON'T compile due to not being able to smart cast external module's properties:
fun solution_no_smartcasts() {
val person = moduleExternal()
if (person.name != null && person.age != null) {
safeCall(person.name, person.age) // ERROR!
}
}
in order to get rid of the smart cast problem first, i came up with the following idea of destructuring:
fun solution_destructure() {
val (name, age) = moduleExternal()
if (name != null && age != null) {
safeCall(name, age)
}
}
ok, but how about that "low level" if? apple's swift would solve it this way:
if let name = person.name as? String, let age = person.age as? Int {
// name and age are non-optional in here
}
so i thought about an extended if which "kind of" solves it:
fun <T1, T2> ifNotNull(x1: T1?, x2: T2?, action: (T1, T2) -> Unit) {
if (x1 != null && x2 != null) {
action(x1, x2)
}
}
fun solution_kotlin_lets() {
val person = moduleExternal()
ifNotNull(person.name, person.age) { name, age ->
safeCall(name, age)
}
}
what are your thoughts on this topic?damian
02/02/2018, 8:20 AMR?
instead of Unit
so we can use it like a let
for multiple types. (with multiLet(a,b) { a, b -> done } ?: somethingElse
gildor
02/02/2018, 8:38 AMfun solution_destructure() {
val person = moduleExternal()
val name = person.name ?: return
val age = person.age ?: return
safeCall(name, age)
}
Also it allows easily replace return
with error()
or some other null handlergildor
02/02/2018, 8:42 AMifNotNull
works too, especially for cases where you want to receive result of expression, not just early return
or break
damian
02/02/2018, 8:43 AM?:
approach with exceptions to pass the error futher down and handle it correctly / display a message why it didn’t work. i like it for this case - if you need to know which value exactly is null for examplegildor
02/02/2018, 8:48 AMuhe
02/02/2018, 9:11 AMifNotNull