Null safety for properties and other operators
One notable difference between Gosu and some other languages is that
property accessor paths in Gosu are null-tolerant, also called null-safe. Only expressions
separated by period (.) characters that access a series of instance
variables or properties support null safety, such as the following form:
obj.PropertyA.PropertyB.PropertyC
In most cases, if any object to the left of the period character is
null, Gosu does not throw a null-pointer exception (NPE) and the
expression returns null. Gosu null-safe property paths tend to simplify
real-world code. Often, a null expression result has the same meaning
whether the final property access is null or earlier parts of the path are
null. For such cases in Gosu, do not check for the null
value at every level of the path. This conciseness makes your Gosu code easier to read and
understand.
For example, suppose you have a variable called
house, which contains a property called Walls, and that
object has a property called Windows. The syntax to get the
Windows value is:
house.Walls.Windows
In some languages, you must be aware that if house
is null or house.Walls is null, your code
throws a null-pointer exception. The following common coding pattern avoids the
exception:
// Initialize to null
var x : ArrayList<Windows> = null
// Check earlier parts of the path for null to avoid a null-pointer exceptions (NPE)
if (house != null and house.Walls != null) {
x = house.Walls.Windows
}
In Gosu, if earlier parts of a pure property path are
null, the expression is valid and returns null. The
following Gosu code is equivalent to the previous example and a null-pointer exception never
occurs:
var x = house.Walls.Windows
By default, method calls are not null-safe. If the right side of a
period character is a method call, Gosu throws a null-pointer exception (NPE) if the value
on the left side of the period is null.
For example:
house.myaction()
If house is null, Gosu throws an NPE. Gosu assumes that method calls might have side effects, so Gosu
cannot skip the method call and return null.
Gosu provides a variant of the period operator that is always
explicitly null-safe for both property access and method access. The null-safe period operator has a
question mark before the period: ?.
If the value on the left of the ?. operator is null, the
expression evaluates to null.
For example, the following expression evaluates left-to-right and contains three null-safe property operators:
obj?.PropertyA?.PropertyB?.PropertyC
Null-safe method calls
A null-safe method call does not throw an exception if the left side of the
period character evaluates to null. Gosu just returns null
from that expression. Using the ?. operator calls the method with
null safety:
house?.myaction()
If house is null, Gosu does not throw an exception. Gosu
returns null from the expression.
Null-safe versions of other operators
Gosu provides null-safe versions of other common operators:
- The null-safe default operator (
?:). You use this operator to specify an alternative value if the value to the left of the operator evaluates tonull. For example:var displayName = Book.Title ?: "(Unknown Title)" // Return "(Unknown Title)" if Book.Title is null - The null-safe index operator (
?[]). Use this operator with lists and arrays. The expression returnsnullif the list or array value isnullat run time, rather than throwing an exception. For example:var book = bookshelf?[bookNumber] // Return null if bookshelf is null - The null-safe math operators (
?+,?-,?*,?/, and?%). For example:var displayName = cost ?* 2 // Multiply by 2, or return null if cost is null
Design code for null safety
Use null-safe operators where appropriate. These operators make code more concise and simplify the handling of edge cases.
You can design your code to take advantage of this special language feature. For example, expose data as properties in Gosu classes and interfaces rather than as setter and getter methods.
See also
