Hey, ruX is here.

Functional kotlin part 1: safe calls

For the seasoned Java it's very easy to switch to kotlin. Even more, thanks to the great effort of team for java interop, there is no need to wait for the greenfield project to start to write kotlin code. You can start straight away by either implementing new functionality in kotlin or converting existing classes into the new language by employing Intellj Idea automagic converter

This is a first of this series of posts unioned by tag #kotlin-showoff

As from my experience it takes literally two days for average developer to switch to kotlin from java and start to write meaningful business logic

As time goes by code can use more kotlin specific constructions which make code much more readable and expressive. In this blog post I'd like to show off some of the nice functional constructions which help to make code more idiomatic.

Extracting data from the nullable types

Say, we have an class Address within UserInfo which holds information about the given user's address. UserInfo is a part of the Person. UserInfo can be nullalbe as well as Address but we want to extract city name. In java it would look like:

    Person person;
    String city;
    if (person.userInfo != null && person.userInfo.address != null && person.userInfo.address.city != null)
        city = person.userInfo.address.city;
    else city = "Unknown city";

    System.out.println("User is in " + city);

If you think it's a safe code I have for you. Savvy java developer can immediately spot the issue - between checks and to city bunch of things can happen on another threads and eventually we can end up with null Hello NPE!

The correct approach would be to capture values while we're performing the check:

    UserInfo userInfo = person.userInfo;
    if (userInfo != null) {
        Address address = userInfo.address;
        if (address != null) {
            city = address.city;
        }
    }
    if (city == null) 
        city = "Unknown city";

    System.out.println("User is in " + city);

Expressivity is not Java best strength. But wait, with Java 8 we can make it a bit more readable (and still safe):

    city = Optional.ofNullable(person.userInfo)
            .map(userInfo -> userInfo.address)
            .map(address -> address.city)
            .orElse("Unknown city");

    System.out.println("User is in " + city);

Looks better, isn't it? Wait for kotlin

println("User is in ${person.userInfo?.address?.city ?: "Unknown city"}")

Sorry java ¯\_(ツ)_/¯

So what exactly happens here? The person.userInfo?.address?.city either city if it's nullnull Then using operator we make expression to return city or string "Unknown city". Even more, we can concatenate everything in one string as an expression

You can eat your cake, and have it too

Is it safe one might wonder? Yes, it is. Look into the generated code:

public final class KotlinImplKt {
   public static final void kotlinImpl() {
      StringBuilder var10000;
      String var4;
      label14: {
         Person person = new Person();
         var10000 = (new StringBuilder()).append("User is in ");
         UserInfo var10001 = person.userInfo;
         if (var10001 != null) {
            Address var3 = var10001.address;
            if (var3 != null) {
               var4 = var3.city;
               if (var4 != null) {
                  break label14;
               }
            }
         }

         var4 = "Unknown city";
      }

      String var1 = var10000.append(var4).toString();
      boolean var2 = false;
      System.out.println(var1);
   }
}

Check out other posts in #kotlin-showoff

Exit mobile version