跳到主要内容
版本:release

赋值表达式

语法

形式语法
1左值表达式 = 表达式
2左值表达式 += 表达式
3左值表达式 -= 表达式
4左值表达式 *= 表达式
5左值表达式 /= 表达式
6左值表达式 %= 表达式
7左值表达式 &= 表达式
8左值表达式 |= 表达式
9左值表达式 ^= 表达式
10左值表达式 <<= 表达式
11左值表达式 >>= 表达式
12左值表达式 := 表达式

描述

赋值表达式用于改变左值表达式所表示的变量或元素的值。

赋值表达式的左侧必须是一个左值表达式(参见 左值表达式),

  • 对于 形式1 的简单赋值表达式:

简单赋值表达式中,除非左值表达式的类型是 mixed 类型,否则右值表达式的类型应当与左值表达式 声明时 的 类型相同,或者为其子类型。

int a = 1;
mixed b = 1;

// a = 3.5; // error: 赋值时不允许从 float 类型隐式转换到 int 类型
a = false; // ok: 允许这么做,可以从子类型隐式转换到父类型

b = 3.5; // ok: mixed 类型可以接受任何类型的值
b = true; // ok: mixed 类型可以接受任何类型的值
  • 对于 形式 2- 11 的运算赋值表达式:

运算赋值表达式等效于 左值表达式 = 左值表达式 <op> 右值表达式 的形式,不过左值表达式只会被求值一次。

例如,a += b 等效于 a = a + ba 只会被求值一次)。运算赋值表达式将按照对应的双目运算符的规则计算, 将计算结果赋值给左值。

运算赋值表达式中,除非左值表达式的类型是 mixed 类型,否则右值表达式的类型应当与左值表达式 声明时 的 类型相同,或者为其子类型。

int a = 10;
a += 5; // a 的值变为 15
// a += 2.5; // error: 赋值时不允许从 float 类型隐式转换到 int 类型

mixed b = 20;
b += 2.5; // ok: mixed 类型可以接受任何类型的值,b 的值变为 22.5
b += true; // ok: mixed 类型可以接受任何类型的值,b 的值变为 23.5
  • 对于 形式 12 的 RO(Readonly)赋值表达式:

与简单赋值表达式类似,但是 RO 赋值表达式的左值应当是一个 被声明为 readonlyparallel 的成员变量,或是一个 parallel 的容器元素。

如果左值表达式是 parallel 的变量或元素,则右值期待一个 parallelreadonly 的值。如果左值表达式是 readonly 的变量或元素,则右值期待一个 readonly 的值。

readonly int a := 10;
parallel array b := [1, 2, 3];

void foo()
{
a := 20; // Ok, a 的值变为 20,简单类型不需要 make_readonly
// a = 30; // Error, 不能通过简单赋值表达式修改

b[0] := 10; // Ok, b 的第一个元素变为 10
// b[1] := [1, 2, 3]; // Error, 不能将一个非 parallel/readonly 的值赋给 parallel 元素
b[1] := make_readonly([1, 2, 3]);
// Ok, b 的第二个元素变为一个 readonly 数组
// b[2] = 20; // Error, 不能通过简单赋值表达式修改

array c = make_parallel([4, 5, 6]);
b := c; // Ok, c 是parallel的
c[1] := 10; // Ok, c 的第一个元素变为 10
// c := [7, 8, 9]; // Error, c 指示的实例是 parallel 的array,但是c本身不是parallel的变量,不能使用 :=
}

对于所有形式的赋值表达式,表达式本身的值类型与左值表达式的类型相同,表达式的值为赋值之后左值表达式的值。

需要注意,赋值表达式能够改变其操作数的值,因此,如果对同一个变量的赋值操作与另一个读取/写入操作出现在同 一条表达式中,并且表达式没有明确的求值顺序(参见 表达式求值顺序), 可能得到意外的结果:

int a = 1;
int b = (a = 3) + a; // 不应当期待 b 的值,避免这种写法

示例

int a = 10;
a = 20; // a 的值变为 20
a += 5; // a 的值变为 25

write(a -= 12); // 输出 13,a 的值变为 13