Nullable types
All datatypes in THP disallow the usage of null
by default.
To represent null
we must use nullable types, represented
by the question mark ?
character.
For instance, a POST request may have a username
parameter,
or it may not. This can be represented with an String?
.
String? new_username = POST::get("username")
thp
When we have a ?Type
we cannot use it directly. We must first
check if the value is null, and then use it.
The syntax ?
returns true
if the value is not null.
if new_username? {
// Here `new_username` is automatically casted to String
}
// you can also manually check for null
if new_username == null {
// This is the same as above
}
thp
We must check explicitly that the value is not null. Doing
if new_username {}
alone is not allowed.
Usage
To create a nullable type we must explicitly annotate the type.
val favorite_color = null // Error, we must define the type
String? favorite_color = null // Ok
thp
Other examples:
fun get_first(Array[String?] values) -> String? {}
val result = get_first([])
thp
Optional chaining
If you have a Type?
and you wish to access a field of Type
if it exists,
you can use the optional chaining operator ?.
.
Person? person = ...
val name = person?.name
thp
- If
person
is null,person?.name
will returnnull
- If
person
is not null,person?.name
will returnname
Null unboxing
The !!
operator transforms a Type?
into Type
.
If you are sure that a value cannot be null
, you can force the
compiler to treat it as a regular value with the !!
operator.
Note the two exclamation marks.
String? lastname = find_lastname()
// Tell the compiler trust me,
// I know this is not null
String s = lastname!!
thp
You can use it to chain access:
val children_lastname = person!!.child!!.lastname
thp
However, if at runtime you use !!
on a null value,
the null value will be returned and your program will
blow up later. So make sure to use this operator
only when you are sure a value cannot be null.
Elvis operator
The Elvis operator ??
is used to give a default value in case a null
is found.
// This is a function that may return a Int
fun get_score() -> Int? {...}
val test_score = get_score() ?? 0
thp
For the above code:
- If
get_score()
is not null,??
will returnget_score()
- If
get_score()
is null,??
will return0
You can use the Elvis operator to return early
val username = get_username() ?? return
thp