====== Covariant Script 表达式 ====== ===== 3.1 定义 ===== **表达式**由操作数和运算符组成 ''操作数 运算符 操作数'' 一般,含左右两个操作数的运算符是**二元运算符** 含一个操作数的运算符是**一元运算符** 二元运算符有**结合律**,有左右结合之分 所有的运算符都有优先级,**优先级越高越先计算**
注意:对于递增、递减、赋值等会修改操作数的运算符,要求表达式的计算结果可被修改,不能是表达式计算中产生的中间临时量或常量
----- \\ ===== 3.2 一元运算符 ===== ^ **运算符** ^ **优先级** ^ **功能** ^ | **-** //表达式// | 10 | 对数值进行取相反数 | | ***** //表达式// | 11 | 对指针进行解引用 | | **typeid** //表达式// | 14 | 获取表达式的运行时类型信息 | | **new** //表达式// | 14 | 新建表达式表示的类型的对象 | | **gcnew** //表达式// | 14 | 新建表达式表示的类型的内存区块 | | **!** //表达式// | 8 | 对表达式进行非运算 | | **++** //表达式// | 13 | 对表达式进行自增运算 | | //表达式// **++** | 13 | 对表达式进行自增运算并保留表达式原先的值 | | **--** //表达式// | 13 | 对表达式进行自减运算 | | //表达式// **--** | 13 | 对表达式进行自减运算并保留表达式原先的值 | ==== 3.2.1 new 表达式 ==== new 表达式 **在栈上新建一个指定类型的对象** 表达式的计算结果需要是一种类型 此对象将会遵从**RAII 原则**自动回收 ==== 3.2.2 gcnew 表达式 ==== gcnew 表达式 **在堆上新建一个指定类型的对象,并返回指向这个对象的指针** 表达式的计算结果需要是一种类型 此对象将会由**垃圾回收器**自动回收 ===== 3.3 二元运算符 ===== ==== 3.3.1 右结合运算符 ==== ^ 运算符 ^ 优先级 ^ 结合律 ^ 功能 ^ | //表达式// ''+'' //表达式// | 10 | 右 | 对数值进行数学加法运算或拼接字符串 | | //表达式// ''-'' //表达式// | 10 | 右 | 对数值进行数学减法运算 | | //表达式// ''*'' //表达式// | 11 | 右 | 对数值进行数学乘法运算 | | //表达式// ''/'' //表达式// | 11 | 右 | 对数值进行数学除法运算 | | //表达式// ''%'' //表达式// | 12 | 右 | 对数值进行数学取余运算 | | //表达式// ''^'' //表达式// | 12 | 右 | 对数值进行数学幂运算 | | //表达式// ''.'' //表达式// | 15 | 右 | 对各种对象进行访问 | | //表达式// ''->'' //表达式// | 15 | 右 | 对指针指向的各种对象进行访问 | | //表达式// ''<'' //表达式// | 9 | 右 | 比较左侧数值是否小于右侧 | | //表达式// ''>'' //表达式// | 9 | 右 | 比较左侧数值是否大于右侧 | | //表达式// ''<='' //表达式// | 9 | 右 | 比较左侧数值是否小于或等于右侧 | | //表达式// ''>='' //表达式// | 9 | 右 | 比较左侧数值是否大于或等于右侧 | | //表达式// ''=='' //表达式// | 9 | 右 | 比较两侧表达式的值是否相等 | | //表达式// ''!='' //表达式// | 9 | 右 | 比较两侧表达式的值是否不相等 | | //表达式// ''&&'' //表达式// | 7 | 右 | 对两侧表达式进行与运算,若左侧为假则停止求值 | | //表达式// ''and'' //表达式// | ::: | ::: | ::: | | //表达式// ''||'' //表达式// | 6 | 右 | 对两侧表达式进行或运算,若左侧为真则停止求值 | | //表达式// ''or'' //表达式// | ::: | ::: | ::: | ==== 3.3.2 左结合运算符 ==== ^ 运算符 ^ 优先级 ^ 结合律 ^ 功能 ^ | //表达式// ''='' //表达式// | 1 | 左 | 将右侧表达式的值赋予左边 | | //表达式// ''+='' //表达式// | 1 | 左 | 对数值进行数学加法运算或对字符串进行拼接后再将其值赋予左边 | | //表达式// ''-='' //表达式// | 1 | 左 | 对数值进行数学减法运算后再赋予左边 | | //表达式// ''*='' //表达式// | 1 | 左 | 对数值进行数学乘法运算后再赋予左边 | | //表达式// ''/='' //表达式// | 1 | 左 | 对数值进行数学除法运算后再赋予左边 | | //表达式// ''%='' //表达式// | 1 | 左 | 对数值进行数学取余运算后再赋予左边 | | //表达式// ''^='' //表达式// | 1 | 左 | 对数值进行数学幂运算后再赋予左边 | === 3.3.2.1 绑定 === 待绑定对象 := 表达式 在这里,待绑定对象必须是**右值**,具体来说就是: - 变量 - 容器中的元素 \\ == 变量的演变 == # 绑定至变量 a := b # 绑定至元素 c := arr[0] \\ == 引用的退化 == a := clone(a) # 绑定至自身的克隆 a := new array # 绑定至新内存区块 \\ ==== 3.3.3 特殊运算符 ==== ^ 运算符 ^ 优先级 ^ 结合律 ^ 功能 ^ | //表达式//'',''//表达式// | 0 | 右 | 联接多个表达式并依次运算 | | //表达式//'':''//表达式// | 4 | 右 | 建立左侧表达式的值到右侧的映射 | | //表达式//''(''//参数列表//'')'' | 15 | 右 | 调用表达式表示的函数 | | //表达式//''[''//表达式//'']'' | 15 | 右 | 访问数组元素、映射类型元素值或是字符串中的元素 | | //表达式//''...'' | 20 | 无 | 若表达式的值为数组,则将其展开 | | ''(''//表达式//'')'' | 无 | 无 | 创建子表达式 | 逗号表达式将遵循从左到右的规则,其值为最后一个表达式的值 ''array''(数组)在访问时,若下标越界会自动增长,增长的部分填''0''(''number''类型);若下标为负则访问下标为长度-下标绝对值的元素,''hash_map''(映射类型)在访问时若映射不存在则将自动建立到''0''的映射 展开表达式的使用范围**仅限**函数调用时的参数列表和数组字面量的声明中 小括号扩起的子表达式将看作以一个整体进行求值 ----- \\ ===== 3.4 三目表达式 ===== 逻辑表达式 ? 表达式1 : 表达式2 逻辑表达式的值为真时三目表达式的值为**表达式1** 逻辑表达式的值为假时三目表达式的值为**表达式2** ----- \\ ===== 3.5 结构化绑定 ===== (表达式1, 表达式2...) = 表达式3 **结构化绑定(Structured Binding)**指的是将数组中的值按位置绑定至小括号括起的逗号表达式列表中,如: (a, b) = {1, 2} 我们将结构化绑定中等号左侧的小括号括起的逗号表达式列表称为结构化绑定列表 **在结构化绑定中要求表达式3(等号右侧)的计算结果必须为数组,结构化绑定列表中的元素需是能够被赋值的左值对象(非临时对象)** 结构化绑定也可以嵌套,但要求嵌套的结构化绑定中对应位置的数组必须也是嵌套的,如: (a, (b, c)) = {1, {2, 3}} 结构化绑定也可以用于变量和常量的声明,但结构化绑定列表中的元素必须为变量名或嵌套的结构化绑定列表,如: var (a, (b, c)) = test(....) constant (d, (e, f)) = {4, {5, 6}} **如果是常量的声明,则被绑定的数组必须为常量** ----- \\ ===== 3.6 lambda 表达式 ===== **定义一个lambda 表达式:** [](参数列表(可选)) -> 表达式 参数列表中的参数只能指定名称,参数名不可重复,各参数之间以逗号分隔 **lambda** 表达式是一种匿名函数,调用 **lambda** 表达式将计算表达式的值并返回 编译器会为 **lambda** 表达式插入一个隐式的 **self** 参数用于表示自身 **lambda** 表达式也可以使用[[manual:reference:grammar:function:main_page#6.2 可变参数|可变参数]]