Handling the million dollar mistake, null reference is a must in modern programming languages. Both Swift and Kotlin has taken similar yet subtly different approach.

Perhaps sharing both together would give one who has view on one to see the other side would be a good comparison.

By default all variables CANNOT be NULL

In Java, if ever a new class object is instantiate, it could either be null or having some value. i.e.

Integer number = null; // Valid

String letter = null; // Valid

Not so for Kotlin and Swift

The below are invalid for Swift and Kotlin

// Swift

let number: Int = nil; // Invalid

let letter: String = nil; // Invalid // Kotlin

val number: Int = null; // Invalid

val letter: String = null; // Invalid

Both introduce a new type to store NULL

Optional in Swift

In Swift, the new type is called Optional. The way to declare it is as below

let number: Int? = nil

let letter: String? = nil print(number) // print `nil`

print(letter) // print `nil`

If you assign a value to it

let number: Int? = 10

let letter: String? = "abc" print(number) // print `Optional(10)`

print(letter) // print `Optional("abc")`

So in another word, it is just a wrapper type (or imagine a box) on the original type (looks similar to Optional<T> of Java, but declared in a more elegant way using ? ).

If want to represent Optional it in a diagram, it would look like below

So you could actually do the below

let number: Int??? = 10

let letter: String??? = "abc" print(number) // print `Optional(Optional(Optional(10)))`

print(letter) // print `Optional(Optional(Optional("abc")))`

Nullable in Kotlin

In Kotlin, the new type is called Nullable. The way to declare it is as below (looks almost the same as Swift, except for the nil isn’t it?)

val number: Int? = null

val letter: String? = null print(number) // print `null`

print(letter) // print `null`

However, if we assign value to it, it will looks as below, behave similar to the non-null version of it.

val number: Int? = 10

val letter: String? = "abc" print(number) // print `10`

print(letter) // print `abc`

How could it be so? This is because the non-null version of the Type is treated as a subclass of the nullable version of the Type

When one declare Int??? or String??? , it is although possible to have such declaration, the compiler will complaint Redundant ‘?’.

It doesn’t make sense to have nullable-nullable-…, given nullable-nullable… is really just nullable. And it’s value still print as a value of it’s non-nullable form shown below.

val number: Int??? = 10 // Warning Redundant ‘?’

vak letter: String??? = "abc" // Warning Redundant ‘?’ print(number) // print `10`

print(letter) // print `abc`

Accessing nullable object’s function

? — Swift Optional Chaining, Kotlin Safe Call

The “?” character is needed before the nullable object’s function could be accessed. Without it, it will produce compilation error, so the potential Null Pointer Exception (NPE) could be prevented.

When “?” is used, when the object is not null, then only it’s function will be executed. Else a null will be return instead.

// Swift Optional Chaining

let string: String? = "ABC"

let nothing: String? = nil

print(string.lowercased()) // Compile error

print(string?.lowercased()) // print `Optional("abc")`

print(nothing?.lowercased()) // print `nil`



// Kotlin Safe call

val string: String? = "ABC"

val nothing: String? = null

print(string.toLowerCase()) // Compile error

print(string?.toLowerCase()) // print `abc`

print(nothing?.toLowerCase()) // print `null`

Non-null to nullable type assignment: Legal

Swift : Wrapping into Optional

It is allowed to assign a non-null to Optional variable of the same type in Swift. It is like wrapping the variable into Optional type

let actualNumber: Int = 10

let actualLetter: String = "abc" print(actualNumber) // print `10`

print(actualLetter) // print `abc` let number: Int? = actualNumber

let letter: String? = actualLetter print(number) // print `Optional(10)`

print(letter) // print `Optional("abc")`

Kotlin : Casting into Nullable

It is allowed to assign a non-null to nullable variable of the same type in Kotlin. It is like casting the variable to it’s parent nullable type, which is legal.

val actualNumber: Int = 10

val actualLetter: String = "abc" print(actualNumber) // result in `10`

print(actualLetter) // result in `abc` val number: Int? = actualNumber

val letter: String? = actualLetter print(number) // result in `10`

print(letter) // result in `abc`

Nullable to non-null type assignment: Error

In both languages, such assignment is not permitted

// Swift

let number: Int? = 1

let letter: String? = "1"

let actualNumber: Int = number // Compile error

let actualLetter: String = letter // Compile error // Kotlin

val number: Int? = 10

val letter: String? = "abc"

val actualNumber: Int = number // Compile error

val actualLetter: String = letter // Compile error

This is where the protection of accidental causing Null Pointer Exception (NPE) from happening, where one can’t accidentally assign a null value to a non-null variable.

Force assign nullable to non-null type

Swift: Unconditional unwrapping

To force an Optional turning into it’s original, one could unwrap it using as!

let number: Int? = 10

let actualNumber: Int = number as! Int

But a shorter way would be as below

let number: Int? = 10

let actualNumber: Int = number!

But these are unsafe, as it will crash in case number == nil .

Kotlin: Force casting, double bang!

To force an casting to a non null value, one could unwrap it using as

val number: Int? = 10

val actualNumber: Int = number as Int

But a shorter way would be as below

let number: Int? = 10

let actualNumber: Int = number!!

But these are unsafe, as it will crash in case number == null .

Graceful assign nullable to non-null type

To make it safe one could do as below

// Swift

let number: Int? = 10

if number != nil {

let actualNumber: Int = number!

} // Kotlin

val number: Int? = 10

if (number != null) {

let actualNumber: Int = number!!

}

However, these looks so yesterday… so Java… so primitive, having to explicitly compare to null.

Let’s look at more elegant way of doing it for both languages.

Swift: Optional Binding

With Optional Binding, no more explicit checking for nil . Note the actualNumber is only scope within the parenthesis.

let letter: String? = "ABC"

if let actualLetter = letter {

print(actualLetter.lowercased())

}

In Swift, there is also a guard that could to handle it gracefully, where it would terminate if the nil is found, or continue. In this case the actualNumber is set beyond the guard scope.

let letter: String? = "ABC"

guard let actualLetter = letter else { return }

print(actualLetter.toLowerCase())

Kotlin: Standard function

In Kotlin, there’s no special syntax introduced to handle that. But there’s a provided generic functions (which is named standard functions) that came in real handy.

The one that was normally used is let as below, but one could use other like apply , run etc.

val letter: String? = 10

letter?.let {

print(it.toLowerCase())

}

The above example is, the it is actually the non nullable of letter that could be used within the scope.

To reads more about Kotlin Function, refer

Graceful handling of null value

In Java world, we do something like below at times.

int messageLength = -1; // -1 to indicate not set if (message != null) {

messageLength = message.length;

} else {

messageLength = 0;

}

Swift: Nil coalescing

In Swift, this is made so much nicer with the ?? (Nil coalescing) operator

let messageLength = message?.count ?? 0

Kotlin: Elvis expression

In Kotlin, this is made so much nicer with the ?: (Elvis expression) operator

val messageLength = message?.length ?: 0

Safe casting : as?

Both Swift and Kotlin allow one attempt to cast one type to another. If casting successful, it will result a nullable type (optional for Swift) of the cast result

// Swift

let number: Int = 10

let x = number as? Int // x = Optional(10), x is Int?

let x = number as? String // x = nil, x is String? // Kotlin

val number: Int = 10

val x = number as? Int // x = 10, x is Int?

val x = number as? String // x = null, x is String?

“After I know it is not null” handling

Sometimes after we are so sure the Optional or Nullable object is not null, it is such a hassle to continue using ? on that object. How does the languages handle such scenario?

Swift: Implicit Unwrapping

Other than having Optional type, Swift provide another type that indicate Implicit Unwrapping type i.e. the Type ends with !

let letter: String? = "ABC"

let unwrapLetter: String! = letter

print(letter) // print `Optional("ABC")`

print(letter?.lowercased()) // print `Optional("abc")`

print(unwrapLetter) // print `Optional("ABC")`

print(unwrapLetter.lowercased()) // print `abc`; no "?" needed

The unwrapLetter above is an implicit unwrapped type. It is actually a optional type, but could be used without the ? type as shown in print(unwrapLetter.lowercased()). Also notice the result is abc instead of Optional("abc") .

This type has make need of having ? unnecessary.

Nonetheless, this type has it’s risk, as it doesn’t guarantee nil will not be there, and will crash when it does.

Kotlin: Smart casting

Unlike Swift, Kotlin doesn’t have another type that does that. But it has a feature call smart casting that comes handy in this case.

Smart casting is a feature is upon knowing that an object is a specific subclass type, it will be automatically cast to that type without the coder have to explicit cast it.

val actualLetter: String? = "ABC"

if (actualLetter == null) return

print(actualLetter.toLowerCase()) // no `?` needed

Te above is a very simplified case, where if actualLetter is null , the function will terminate. This means after that line, we’ll know that actualLetter is confirm not null .

With this, actualLetter is now smartly cast to String , and could call toLowerCase() without need the safe call ? operator.

Smart casting is only performed if the variable is confirmed not changeable between the check and the usage. Hence it is safe.