# 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?`. ```thp String? new_username = POST::get("username") ``` When we have a `Type?` we cannot use it directly. We must first check if the value is null, and then use it. ```thp if new_username != null { // Here `new_username` is automatically casted to String } ``` 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. ```thp val favorite_color = null // Error, we must define the type String? favorite_color = null // Ok ``` Other examples: ```thp fun get_first(Array[String?] values) -> String? {} val result = get_first([]) ``` ## 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. ```thp Person? person = ... val name = person?.name ``` - If `person` is null, `person?.name` will return `null` - If `person` is not null, `person?.name` will return `name` ## Elvis operator The Elvis operator `??` is used to give a default value in case a `null` is found. ```thp // This is a function that may return a Int fun get_score() -> Int? {...} val test_score = get_score() ?? 0 ``` For the above code: - If `get_score()` is not null, `??` will return `get_score()` - If `get_score()` *is* null, `??` will return `0` You can use the Elvis operator to return early ```thp val username = get_username() ?? return ```