**空值结合运算符**（在Perl中**称逻辑定义或运算符**）是一种二元运算符，是多种编程语言的基本条件表达式语法的一部分，包括C#、PowerShell 7.0.0、Perl 5.10，Swift，PHP 7.0.0。虽然其行为因实现而异，但空值合并运算符首先考虑返回其左操作数的值（如果左操作数存在且不为空） ，其次考虑返回右操作数的值。此行为可为特定值不可用的情况定义缺省值。

与三元条件表达式 `x?x:y`中表达式x可能求值2次相比，空值结合运算符更类似二元埃尔维斯运算符`x?:y`，操作数求值至多一次，这在x的求值有副作用情况下特别有意义。

编程语言用法
------

### Bash

Bash中，"如果参数未设置或为空，则用缺省值替代"：

```
#supplied\_title='supplied title' # Uncomment this line to use the supplied title
title=${supplied\_title:-'Default title'}
echo "$title" # prints: Default title

```

### C#

C#中，空值结合运算符是`??`.常用于简化表达式：

```
possiblyNullValue ?? valueIfNull

```

例如，如果希望C#源码给一个页缺省页标题：

```
string pageTitle = suppliedTitle ?? "Default Title";

```

以代替更啰嗦的实现：

```
string pageTitle = (suppliedTitle != null) ? suppliedTitle : "Default Title";

```

或者

```
string pageTitle;

if (suppliedTitle != null)
{
 pageTitle = suppliedTitle;
}
else
{
 pageTitle = "Default Title";
}

```

上述3种实现给`pageTitle`相同的结果。

注意表达式`suppliedTitle`在`??`运算符下求值1次，而在另外2种代码例子种可能求值2次。

该运算符在同一个表达式可以使用多次：

```
return some\_Value ?? some\_Value2 ?? some\_Value3;

```

从C# 8.0起，支持`??=`空值结合赋值运算符：

```
some\_Value ??= some\_Value2;

```

以代替啰嗦的写法：

```
some\_Value = some\_Value ?? some\_Value2;

```

结合使用空值条件运算符（英语：）`?.`或空值条件成员访问运算符`?[]`，空值结合运算符可在对象为空或对象的成员为空时提供缺省值。例如，下述例子中`page`对象为空或者`page`不为空但其属性`Title`为空，则提供缺省值：

```
string pageTitle = page?.Title ?? "Default Title";

```

### JavaScript

JavaScript最接近的运算符是`??`, 即"nullish coalescing operator"，从ECMAScript第11版引入。当左端操作数不为"nullish" (`null`或`undefined`)，取其值作为结果，否则取右端操作数作为结果。 例如：

```
const a = b ?? 3;

```

逻辑或运算符(`||`)对任何布尔假值：`null`, `undefined`, `""`, `0`, `NaN`, `false`，都会取右端操作数的值。

### Python

Python没有空值结合运算符。可用条件表达式模拟其功能：

```
now() if time is None else time

```

Python的`or`运算符提供了类似但不同的行为。区别在于，如果左操作数的结果为`False`，`or`也会返回右操作数的值：

```
42    or "something"  # returns 42
0     or "something"  # returns "something"
False or "something"  # returns "something"
""    or "something"  # returns "something"
None  or "something"  # returns "something"

```

而真正的空值结合运算符仅在最后一种情况下返回结果`"something"`，而在左操作数为(`0`, `False`, `""`)时返回响应值。 

### PowerShell

PowerShell 7 提供了`??`空值结合运算符：

```
$myVar = $null
$x = $myVar ?? "something" # assigns "something"

```

### SQL

Oracle的PL/SQL, NVL()函数提供了这种输出：

```
NVL(possibly\_null\_value, 'value if null');

```

SQL Server/Transact-SQL有ISNULL函数，其原型为：

```
ISNULL(possibly\_null\_value, 'value if null');

```

注意*ISNULL*与*IS NULL*不同，后者判断表达式是否为空。

ANSI SQL-92标准包括了一个COALESCE函数，在Oracle, SQL Server, PostgreSQL, SQLite and MySQL.都被实现了。COALESCE函数返回第一个不为空的参数的结果，如果所有参数都为空，则返回空。

```
COALESCE(possibly\_null\_value[, possibly\_null\_value, ...]);

```

### VB.NET

VB.NET中的`If`运算符/关键字得到空值结合运算符的效果。 

```
Dim pageTitle = If(suppliedTitle, "Default Title")

```

这比下述写法更精炼：

```
Dim pageTitle = If(suppliedTitle <> Nothing, suppliedTitle, "Default Title")

```

参考文献
----

1. ↑  BillWagner.. msdn.microsoft.com.  [2021-08-23]. （原始内容存档于2017-03-17）.
2. ↑ .  [2021-08-30]. （原始内容存档于2019-12-27）.
3. ↑ . Ecma International. June 2020  [2021-08-30]. （原始内容存档于2020-12-23）.
4. ↑
5. ↑ . docs.oracle.com.  [2021-08-30]. （原始内容存档于2021-08-30）.
6. ↑ . technet.microsoft.com.  [2021-08-30]. （原始内容存档于2017-08-26）.
7. ↑ . www.postgresql.org.  [2021-08-30]. （原始内容存档于2018-03-09）.
8. ↑ . www.sqlite.org.  [2021-08-30]. （原始内容存档于2022-01-18）.
9. ↑ . dev.mysql.com.  [2021-08-30]. （原始内容存档于2019-12-26）.
10. ↑  dotnet-bot.. docs.microsoft.com.  [2021-08-30]. （原始内容存档于2022-01-21）.