Does anyone else’s company not let them use !! any...
# announcements
b
Does anyone else’s company not let them use !! anywhere, no exceptions?
l
Where would you need to use it? I always add
?: throw Exception("foo")
instead, so it's handled with a descriptive exception
6
b
For me it was interop with java classes that don’t have @NonNull annotations
Copy code
var x: Int? = null
fun test(): Int {
    var y = x
    if (y == null) {
        y = someJavaFunctionThatDoesntReturnNull()
    }

    return 1 + y!!
}

fun someJavaFunctionThatDoesntReturnNull(): Int = 1
p
fun test() = (x ?: someJavaFunctionThatDoesntReturnNull()) +1
b
That works too. But my use-case is more complex than that
v
!!
is a perfectly reasonable language feature. There is nothing wrong with it. Having a blanket ban on a language construct does not sound like a thought out decision
l
yes, my company does not let me. double bang is a big no no
m
@Vlad so,
goto
is fine to use then? 😄
v
I don't think this is a fair comparison. There are lots of valid use cases for
!!
that don't bring it nowhere close to the issues usually attributed to goto
c
This seems like a terrible rule, but some people rather be in some super weird state instead of crash. There are reasons to use ?, !!, ?: etc. Having a ban seems unreasonable. There are definitely times where something should not be null and you don't want to propagate a null value. ? saves you from NPE, but will still propagate a null. Causing you to have weirdness or fail further down the line/further from the truth of the issue.
f
I really don't get banning
!!
but allowing
?: throw...
s
Usually
!!
is a code smell, but sometimes it is not. Outright banning it makes no sense in my opinion. If you do, folks will do this `x ?: throw NullPointerException("...")`…. 🤷‍♂️
t
@Marko Mitic
goto
did have perfectly valid use cases in C 😄
j
We use checkNotNull / requireNotNull which allows custom error message with more information of context if needed
1
l
I was actually told not to on the interview! I used them in my coding problem
w
I really don’t get banning
!!
but allowing
?: throw...
To me
!!
is typically
yeah it's null but I don't care
, while
?: throw
requires you to think why it could be null, and come up with appropriate message. And in case being not-null is an invariant then
checkNotNull
better conveys “I know it’s never null”. Similarly
requireNotNull
is appropriate to tell “This parameter should not be null so you messed up this invocation”. Anyway I don’t think I’ve seen legitimate usage of
!!
other than being lazy and not wanting to provide message/refactor code a bit. It’s mostly people doing
if (field != null) field!!.doSomething()
too, so I also get why it’s difficult for some to see why it’d be useful. I wonder if Kotlin would have
!!
operator if it wasn’t for Java interop
1
👍 2
p
I looked through my code and found this:
val foo:Int = listOf(fooService.getFoo(), barService.getBar(), bazService.getBaz()).max()!!
the list will never be empty and it’s obvious that it isn’t to any reader
w
🤔 I agree this looks like a reasonable usage of
!!
. Personally I’d still write ``listOf(…).max().let(::checkNotNull)` but I guess this just proves the point that some people just don’t like
!!
🙂 Anyway I think forbidding
!!
also serves junior developers, since typically having to use it means there’s something iffy with your code (like the field I mentioned before)
p
I completely agree that usually,
!!
can be expressed better in other ways. And having a general rule against that operator is a good idea. But, this rule, just like most other rules, has exceptions
👍 1
g
Hmm, but why do you need listOf().max() in this case? Why not
maxOf
function
p
In this particular case, yes. But of I had 4 things or 5?
y
The point is that there are cases (e.g. calling
max()
on a list that is never empty) where you the programmer knows that some thing cannot be null, but the compiler can’t prove it
Cases like these are where things like
!!
becomes necessary
I really like the
?: throw Exception(...)
solution for cases like these
g
also
?: error(...)
In this particular case, yes. But of I had 4 things or 5?
Create function
maxOf
with vararg argument. I actually surprised that its’ not there In general it looks as a good example when “I know it’s not null, give me my double bang” should be replaced with more efficient and much more idiomatic function (from stdlib or your own) Even super simple extension like
maxOrThrow()
would be better because provides much better error message
But I want to be clear, I’m not for any restrictions in code style about this, or of language, I’m just trying to say that many cases it’s actually good recommendation, to wait a second and ask yourself “can I improve it by avoiding nullability or at least by providing some meaningful error message”, actually investigate such KotlinNullPointerExceptions is not so easy in many cases because you not always have context, sometimes they are caused by Java interop and line where it crashed not always enough Also in my career I saw too many “ImpossibleExceptions” on prod
s
I’m pretty sure this works:
Copy code
fun test(): Int {
    val y:Int = x ?: someJavaFunctionThatDoesntReturnNull()
    return 1 + y
}
Can’t you always assign a platform type to a non-nullable type, as long as you make the type of the variable explicit!?!
g
Yes, but it works only for Java types and only if those types are not annotated with Nullability annotations
👍🏼 1
c
@gildor
also
?: error(...)
I'm unfamiliar with that. What's error()?
g
@Colton Idle This is a function from standard library (also in package
kotlin
so doesn’t require import: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/error.html
c
@gildor that's really helpful. It's like a quick way to create a IllegalStateException with a message. 👍 TIL