You can also do this this to avoid the unsafe !! o...
# getting-started
k
You can also do this this to avoid the unsafe !! operator using the elvis operator and `let`:
Copy code
fun main(args: Array<String>) {
    val map = mutableMapOf<String, Int>()
    val lst = mutableListOf<Int>()
    map["answer"] = 42

    for (arg in args) {
        map[arg]?.let { 
            lst.add(it)
        }
    }
}
b
I would, but I need an else in my specific use case.
d
You could always use
map[arg]?.let { ... } ?: <stuff to do when it's null>
which may or may not look better to you.
k
It surely is better then using !!.
d
I would definitely use ?: on my own projects, I haven’t come to a conclusion about what I would decide for “projects with other people”.
b
Can you not do block statements after ?: ? This doesn't compile:
Copy code
for (arg in args) {
    map[arg]?.let {
        lst.add(it)
    }?: {
        lst.add(0)
    }
}
k
No, you need to actually call it. Try
?: run {...}
or
?: {...}()
I'd go for the former.
d
run
is better in my opinion. Or you could refactor your contingency plan into its own method and call that depending on what kind of local context you need.
b
I might do that, looks a bit convoluted now. Learned a lot though 👌
r
Personally I think the whole
Copy code
someFun()?.let {
    ...
} ?: run {
    ...
}
is so much less clear than just
Copy code
val someVal = someFun()
if (someVale != null) {
    ...
} else {
    ...
}
Sure it's technically a one liner, but Kotlin was designed to be clear, concise, and explicit, not cryptic 😛
(not to mention the potential downside of accidentally returning a
null
in the
let
block will also run the
run
block in the first example)
k
Huh I didn't know that, learned something new today!
r
I made that mistake once when I accidentally left a nullable variable on the last line, not noticing it was the return value. I thought it was a bug in the std-lib for a while till I realized my (stupid) mistake. 😜
d
If you don’t need the result couldn’t you use
apply
instead of
let
and avoid that trap?
k
apply
doesn't work, that uses the extension function thing.
also
works nicely though.
Now I'm wondering why using
let
is an idiom at all...
d
apply
should work because it returns the receiver ie. null or not null, rather than the result of the closure you pass in.
k
Right but
apply
isn't a drop-in replacement for
let
, the
it
-syntax doesn't work.
Where
also
is one.
d
Ah, you’re correct, you would have to use
this
in apply.
r
It's an insanely rare edge case. I still use
?.let { ... }
, but usually only when it actually returns a value, not as a shortcut to
if
. Though it's just a personal preference.
@karelpeeters
let
has always been in the language, whereas
also
is relatively new, so it became the idiom.
k
Right, that's the case where
let
is useful.
I don't think I'll ever be able to remember all of those methods, do their names even have any meaning?
r
I'm not sure what you mean. The names seem reasonable to me.
k
I don't know if it's just me but I can't really picture what a method called
let
would do. Same for
also
...