Nullable types - patterns for getting rid of them?


#1

Hi,

I’m curious what other Kotlin programmers are doing here. I of course agree that it’s a step up from Java to be explicit about nullable types. But I’m finding that sometimes I have a hard time creating my objects with all their fields initialized from the start, and then the code is polluted with some amount of !!, which I don’t like.

For example, in some Kotlin/JS I have some Controller objects – one for each tab in the UI. These controllers setup some DOM only when the user clicks a tab. I’ve also had some state machines where variables aren’t initialized until that state is reached.

So, I’m curious…

  • How rare is !! in your code?
  • Are there some common techniques for dealing with situations like I described.

I’ve been using Swift and Kotlin lately. Swift has another nullable variation…

 var foo: Foo!

which goes back to the old way. It’s like Foo? except the !! is implicit when you reference it. I wonder if a similar thing is possible in Kotlin, or might someday be possible.

Rob


#2

Have you looked into lateinit?

I find that using it removes the need for most of my !! (which I try to avoid as much as possible).


#3

Aha, that is what I was looking for. Thanks! I searched for lazy, which I guess could also be useful in some of these cases, but I had missed lateinit.

Rob


#4

I would note that for state machines, you probably do want nullable types, as the type system is preventing you from getting confused and trying to access state that might not actually be there yet. The lateinit modifier is intended for the case where a reflection based framework is injecting stuff into your classes fields right at the start, or where something is being initialised in a method called from the c’tor but not actually in the c’tor.

Kotlin internally has the same thing as Swift: a reference that came from Java is written as Foo! and null safety is disabled for that reference. However you cannot write this yourself in the language: if you write a type, you always have to pick.

There are a variety of useful patterns to help you get rid of the !!s. One is to realise that if you assign the result to a local on-stack val, you don’t need to do it again each time. Another is to use ?.let { … } where the value “it” will be non-null inside the block.