The null coalescing operator (called the Logical Defined-Or operator in Perl) is a binary operator that is part of the syntax for a basic conditional expression in several programming languages, including C#,Perl as of version 5.10,Swift, and PHP 7.0.0. While its behavior differs between implementations, the null coalescing operator generally returns the result of its first operand if it exists and is not null.
In contrast to the ternary conditional if operator used as , but like the binary Elvis operator used as , the null coalescing operator is a binary operator and thus evaluates its operands at most once, which is significant if the evaluation of has side-effects.
Examples by languages
In Bash "If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted":
In C#, the null coalescing operator is . It is most often used to simplify null expressions as follows:
For example, if one wishes to implement some C# code to give a page a default title if none is present, one may use the following statement:
instead of the more verbose
The three forms are logically equivalent.
The operator can also be used multiple times in the same expression:
Once a non-null value is assigned to number, or it reaches the final value (which may or may not be null), the expression is completed.
As of ColdFusion 11,Railo 4.1,CFML supports the null coalescing operator as a variation of the ternary operator, . It is functionally and syntactically equivalent to its C# counterpart, above. Example:
Clojure's or macro works similarly.
You can also chain values.
The null value is not normally used in F# for values or variables. However null values can appear for example when F# code is called from C#.
F# does not have a built-in null coalescing operator but one can be defined as required as a custom operator:
This custom operator can then be applied as per C#'s built-in null coalescing operator:
Missing values will normally cause exceptions. However, both missing and null values can be handled, with an optional default value:
or, to leave the output blank:
Types in Haskell can in general not be null. Representation of computations that may or may not return a meaningful result is represented by the generic Maybe type, defined in the standard library as
The null coalescing operator replaces null pointers with a default value. The haskell equivalent is a way of extracting a value from a Maybe by supplying a default value. This is the function fromMaybe.
Some example usage follows.
Kotlin uses the '?:' operator. This is an unusual choice of symbol, given that ?: is typically used for the Elvis operator, not null coalescing, but it was inspired by Groovy (programming language) where null is considered false.
In Obj-C, the nil coalescing operator is . It can be used to provide a default for nil references:
This is the same as writing
In Perl (starting with version 5.10), the operator is and the equivalent Perl code is:
The possibly_null_value is evaluated as null or not-null (or, in Perl, undefined or defined). On the basis of the evaluation, the expression returns either value_if_null when possibly_null_value is null, or possibly_null_value otherwise. In the absence of side-effects this is similar to the way ternary operators ( statements) work in languages that support them. The above Perl code is equivalent to the use of the ternary operator below:
This operator's most common usage is to minimize the amount of code used for a simple null check.
Perl additionally has a assignment operator, where
is largely equivalent to:
This operator differs from Perl's older and operators, as those operators will treat 0 or '' (a zero-length string) as equivalent to null/undefined. For example:
PHP 7 has introduced a null-coalescing operator with the syntax. This checks strictly for NULL or a non-existent variable/array index/property. In this respect, it acts similarly to PHP's pseudo-function:
A future version of PHP will add the Null Coalescing Assignment Operator with the syntax:
In Scheme, "boolean false" and "null" are represented by the same value, written as . Furthermore, is the only value in Scheme that is treated as false by boolean operators, unlike some other languages, in which values like 0, the empty string, and the empty list may function as false. The boolean 'or' operation, written as , returns if it is not false, otherwise it returns . Thus, in Scheme, there is no need for a separate "null coalescing operator", because the operator serves that purpose.
In Oracle's PL/SQL, the NVL() function provides the same outcome:
In SQL Server/Transact-SQL there is the ISNULL function that follows the same prototype pattern:
Attention should be taken to not confuse ISNULL with IS NULL – the latter serves to evaluate whether some contents are defined to be NULL or not.
The ANSI SQL-92 standard includes the COALESCE function implemented in Oracle,SQL Server,PostgreSQL,SQLite and MySQL. The COALESCE function returns the first argument that is not null. If all terms are null, returns null.
In Swift, the nil coalescing operator is . It is used to provide a default when unwrapping an optional type:
For example, if one wishes to implement some Swift code to give a page a default title if none is present, one may use the following statement:
instead of the more verbose
In VB.NET the If operator/keyword achieves this.
which is a more concise way of using its variation
Here is some history on the syntax in question.
In classical C, error handling was frequently done by writing something like:
Or, whenever there was a function call that might return a null pointer, the idiom was used the other way round:
However, this syntax is dangerously close to
which is why many people consider the assignment inside a condition bad style, and compilers started to warn about it (at least with ). However, this warning can be avoided by adding an extra set of parentheses:
Then C99 came around, allowing you to mix definitions and statements, so many developers would frequently write something like
which does feel awkward. This is why the newest standard allows definitions inside conditions, to provide a short, elegant way to do this:
There is no danger in this statement anymore, you explicitely give the variable a type, obviously wanting it to be initialized. It also avoids the extra line to define the variable, which is nice. But most importantly, the compiler can now easily catch this sort of bug:
Without the variable definition inside the statement, this condition would not be detectable.
To make a long answer short: The syntax in you question is the product of old C's simplicity and power, but it is evil, so compilers can warn about it. Since it is also a very useful way to express a common problem, there is now a very concise, bug robust way to achieve the same behaviour. And there is a lot of good, possible uses for it.