基础语法:算术运算、逻辑运算、自定义运算
二、运算符#
1. 运算符分类与优先级#
优先级从高到低(数值越大优先级越高)
| 优先级 | 运算符/结构 | 示例/说明 |
|---|---|---|
| 13 | 括号 () | (a + b) * c |
| 12 | 单目运算符 !, -, __.. | !flag, -5 |
| 11 | 幂运算 ^ | 2 ^ 3 |
| 10 | 乘除模 *, /, %, _*.. | a * b % c |
| 9 | 加减 +, - ,_+.. | a + b - c |
| 8 | 比较 ==, !=, >等 | a >= b |
| 7 | 逻辑与 && | cond1 && cond2 |
| 6 | 逻辑或 || | cond1 || cond2 |
| 5 | 条件运算符 ? : | cond ? t : f |
| 4 | Lambda 表达式 -> | x -> x+1 |
| 3 | 错误处理 ?: ?. | 3 / 0 ?: 1 |
| 2 | 管道 | | ls -1 | sort |
| 2 | 重定向 << >> >! | date _ >> /tmp/day.txt |
| 1 | 赋值 =, := ? | x = 5, let y := 10 |
管道和重定向同级,逻辑运算比管道和重定向优先级更高。
2. 空格规则#
| 运算符类型 | 是否需要空格 | 示例 |
|---|---|---|
| 常规运算符 | 两侧应空格 | a + b, x <= 10 |
| 非严格模式,部分符号两侧可以不空格 | a+b, x<=10, a=5 | |
-和/应空格 | b-3为字符串,3- b为减法 | |
| 自定义运算符 | 必须用下划线开头且两侧空格 | x _*+ y, a _?= b |
| 后缀运算符,必须用双下划线开头且空格 | x __*+ | |
| 前缀运算符 | 前面为空格或开始,后面无空格 | !x, -7 |
| 中缀运算符 | 前后均无空格 | dict.key, 1..9 |
| 后缀运算符 | 前后均无空格 | func(a), array[i], 10M |
自定义操作符
自定义操作符是以
_开头的符号,只能包含符号,不能包含数字或字母。自定义单目运算符 以
__开头,如__+, 优先级同单目运算符。仅能用于后缀运算。自定义+级运算符 以
_+开头,如_+%,优先级同+-自定义*级运算符 以
_*开头,如_*-,优先级同*/1let __++ = x -> x + 1; 23 __++
3. 特别的操作符#
==!=带类型相等比较.~=!~=值相等比较.~:!~:是否包含(可用于字符串,数组,区间,字典(检测是否包含指定key). 支持正则包含检测。
举例:
15 == "5" # False
25 ~= "5" # True
3"abc" ~: "a" # True
40..<8 ~: 8 # False
50..8 ~: 8 # True
6"abc" ~: '\d' # False4. 四则运算#
+-*/是已经重载的运算符 除了可以完成数字的四则运算外,还可以完成更复杂的运算%^仍为普通运算,只支持数字之间的运算。
加法 +#
数字
数字 + 数字 = 数字以高精度相加
11 + 2.5 # → 3.5数字 + 字符串 = 以数值相加
11 + "2.5" # → 3.5数字 + 列表 = 一起求和
11 + [2.5,3] # → 6.5
字符串
字符串 + 字符串 = 字符串连接
1"1" + 2.5 # → "12.5"字符串 + 列表 = 一起串联
1"1" + [2,3] # → "123"
区间
- 区间 + 整数 = 区间扩充(正数从尾部,负数从头部)
10..8 + 2 # → 0..10 20..8 + (-2) # → 2..8
列表
列表 + 列表 = 列表合并
1[1,2] + [3,4,5] # → [1,2,3,4,5]列表 + 其他 = 向列表插入值
1[1] + 2.5 # → [1,2.5]
映射
映射 + 映射 = 映射合并
1{a:b} + {c:d} # → {a:b,c:d}映射 + 其他 = 向映射插入值
1{a:b} + c # → {a:b,c:c}
字节
- 字节 + 字节 = 字节追加
- 字节 + 字符串 = 字节追加
其他情况抛出异常
减法 -#
数字
数字 - 数字 = 数字以高精度相减
11 - 2.5 # → -1.5数字 - 字符串 = 以数值相减
11 - "2.5" # → -1.5
字符串
字符串 - 字符串 = 字符串移除(首次出现)
1"i am lume" - "a" # → "i m lume"字符串 - 浮点数 = 字符串移除(首次出现)
1"i am lume v4.2" - 4.2 # → "i am lume v"字符串 - 整数 = 字符串移除(正数从尾部,负数从头部)
1"98101" - 1 # → "9801" 2"98101" - (-2) # → "101"
超出长度则返回空字符串
区间
- 区间 - 整数 = 区间缩放(正数从尾部,负数从头部)
10..8 - 2 # → 0..6 20..8 - (-2) # → -2..8
列表
列表 - 列表 = 列表差集
1[1,2,3,4,5] - [3,4,5] # → [1,2]列表 - 其他 = 列表移除
1[1,2,3] - 2 # → [1,3]
映射
映射 - 映射 = 映射差集
1{a:b,c:d} - {c:d} # → {a:b}映射 - 其他 = 映射键移除
1{a:b,c:d} - c # → {a:b}
其他情况抛出异常
乘法 *#
数字
- 数字 * 数字 = 数字相乘
12 * 2.5 # → 5 - 数字 * 字符串 = 以数值相乘
12 * "2.5" # → 5
字符串
字符串 * 整数 = 字符串重复
1"2" * 5 # → "22222"列表 * 列表 = 矩阵乘法
1[[1,2,3],[4,5,6]] * [[7,8],[9,10],[11,12]] 2 3# → 返回 4 +----------+ 5 | C0 C1 | 6 +==========+ 7 | 58 64 | 8 | 139 154 | 9 +----------+
矩阵乘法要求维度正确 如内部有缺失元素,计算时会以0填充
- 列表 * 数字 = 每个元素乘法
1[1,2,3] * 2.5 # → [2.5,5,7.5]
除法 /#
数字
- 数字 / 数字 = 数字相除
15 / 2 # → 2 25 / 2.0 # → 2.5 - 数字 / 字符串 = 以数值相除
15 / "2" # → 2 25.0 / "2.5" # → 2
列表
- 列表 / 数字 = 每个元素除法
1[2,4,6] / 2 # → [1,2,3]
5. 隐式类型转换#
数字之间的运算,自动向高精度类型转换。 不同类型数据相加,总是尝试自动转为第一个数据的类型。
1# 非严格模式
23 + "5" # → 8(自动转为整数)
3"10" + 2 # → "102" (自动转为字符串)
4"10" * 2 # → "1010" (字符串重复)
5[1,2,3] + 5 # → [1,2,3,5]
6[2,3] - 2 # → [3]
70..8 + 3 # → 0..11
8{name:wang, age:18} - name # → {age:18}6. 增量运算符#
+=-=*=/=只适用于数字运算。
对于未初始化的,自动初始化为0
和四则运算不同的是,对于非数字会返回None,而不是抛出异常。 如:
1a += 1 # → 1
2a += [1] # None边缘情况:
- 除以零会报错。
7. 逻辑运算符#
&&||返回Bool值 他们会把左右两侧的值转为Bool值并进行逻辑运算。如:
1False && print a # 不执行打印,返回False
2True && print a # 执行打印,返回False,因为右侧语句返回None与Bash比较 逻辑运算符不同于Bash,而是与其他编程语言中的含义相同,只是进行纯粹的逻辑运算。
- 在Bash中,
&&表示左侧执行成功才执行右侧,不返回值。 - 在Lumesh中,
&&表示左侧返回True才计算右侧,始终返回布尔值。 类似的, - 在Bash中,
||表示左侧执行失败才执行右侧,不返回值。 - 在Lumesh中,
||表示左侧返回False才计算右侧,始终返回布尔值。
- 在Bash中,
要实现类似Bash中的效果,可以:
- 左侧执行成功才执行右侧:
left_arm ; right_arm - 左侧执行失败才执行右侧:
left_arm ?: right_arm
8. 选择运算符#
test ? t : f
等同于 if test { t } else { f}
支持嵌套,如test?t:b?tb:fb
三、自定义运算符#
自定义单目运算符#
自定义单目运算符必须以__开头,定义后,作为后缀运算符使用。
1# 定义
2let __! = x -> Math.sum(x)
3# 使用
4[5,6,7] __! # 18为何不定义前置运算符? 因为和函数调用方式类似,还不如直接定义函数。 如果您认为有使用的必要,可以到项目主页提交请求。
自定义双目运算符#
自定义单目运算符必须以_开头(但不以__开头),定义后,作为双目运算符使用。
1# 定义自定义运算符
2let _+ = (a, b) -> a.concat(b) # 自定义加法
3
4# 使用自定义运算符
5[1, 2] _+ [3, 4] # [1, 2, 3, 4]双目运算符涉及到运算优先级。
- 以
_+开头的,优先级同加法。 - 以
_*开头的,优先级同乘法。 - 以
_开头的其他运算符,优先级高于幂运算,低于单目运算(如!)。