这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
AviatorScript 支持常见的类型,如数字、布尔值、字符串等等,同时将大整数、BigDecimal、正则表达式也作为一种基本类型来支持。
数字
数字包括整数和浮点数,AviatorScript 对 java 的类型做了缩减和扩展,同时保持了一致的运算符规则。
整数和算术运算
整数例如 -99、0、1、2、100……等等,对应的类型是 java 中的 long 类型。AviatorScript 中并没有 byte/short/int 等类型,统一整数类型都为 long,支持的范围也跟 java 语言一样:-9223372036854774808~9223372036854774807。
整数也可以用十六进制表示,以 0x
或者 0X
开头的数字,比如 0xFF(255)、0xAB(171) 等等。
整数可以参与所有的算术运算,比如加减乘除和取模等等。
1 | css复制代码let a = 99; |
加减乘除对应的运算符就是 +,-,*,/
这都比较好理解,取模运算符就是 %
,规则和语法和 java 是一样的。
需要注意,整数相除的结果仍然是整数,比如例子中的 a/b
结果就是 0,遵循 java 的整数运算规则。
运算符之间的优先级如下:
- 单目运算符
-
取负数 *, /
+,-
整个规则也跟 java 的运算符优先级保持一致。你可以通过括号来强制指定优先级,比如例子中的 a-(b-c)
就是通过括号,强制先执行 b-c
,再后再被 a 减。
通常来说,复杂的算术表达式,从代码可读性和稳健角度,都推荐使用括号来强制指定优先级。
大整数(BigInt)
对于超过 long 的整数, AviatorScript 还特别提供了大整数类型的支持,对应 java.math.BigInteger
类。任何超过 long 范围的整数字面量,会自动提升为 BigInteger
对象(以下简称 BigInt),任何数字以 N
字母结尾就自动变 BigInt:
1 | ini复制代码## examples/bigint.av |
10223372036854774807
是一个远远超过 long 返回的数字,b 也是 BigInt 类型,因为它以 N
结尾,BigInt 的算术运算和一般整数没有什么两样,采用同样的算术运算符和规则,执行这段脚本将打印
1 | 复制代码10223372036854774807 |
请注意,默认的 long 类型在计算后如果超过范围溢出后,不会自动提升为 BigInt,但是 BigInt 和 long 一起参与算术运算的时候,结果为 BigInt 类型。关于类型转换的规则,我们后面再详细介绍。
浮点数
数字除了整数之外,AviatorScript 同样支持浮点数,但是仅支持 double 类型,也就是双精度 64 位,符合 IEEE754 规范的浮点数。传入的 java float 也将转换为 double 类型。所有的浮点数都被认为是 double 类型。浮点数的表示形式有两种:
- 十进制的带小数点的数字,比如
1.34159265
,0.33333
等等。 - 科学计数法表示,如
1e-2
,2E3
等等,大小写字母e
皆可。
看一个简单例子,牛顿法求平方根
1 | ini复制代码## examples/square_root.av |
这个例子稍微复杂了一点,因为我们用了后面才会讲到的 while 循环语句(参见条件语句),不过整体逻辑还是比较简单的,求 2 的平方根,我们通过不停计算 (a/root + root)/2.0
的值,看看是否在误差范围( err
指定)内,不在就继续迭代计算,否则就跳出循环打印结果:
1 | csharp复制代码square root of 2 is: 1.414213562373095 |
浮点数的运算符跟整数一样,同样支持加减乘除,优先级也是一样。浮点数和浮点数的算术运算结果为浮点数,浮点数和整数的运算结果仍然为浮点数。
高精度计算(Decimal)
浮点数是无法用于需要精确运算的场景,比如货币运算或者物理公式运算等,这种情况下如果在 Java 里一般推荐使用 BigDecimal
类型,调用它的 add/sub 等方法来做算术运算。
AviatorScript 将 BigDecimal
作为基本类型来支持(下文简称 decimal 类型),只要浮点数以 M
结尾就会识别类型为 deicmal,例如 1.34M
、 0.333M
或者科学计数法 2e-3M
等等。
decimal 同样使用 +,-,*,/
来做算术运算, AviatorScript 重载了这些运算符的方法,自动转成 BigDecimal
类的各种运算方法。我们把求平方根的例子改成 decimal 运算
1 | ini复制代码## examples/bigdecimal.av |
运算结果 root
的类型也是 decimal
。除了 double 以外的数字类型和 decimal 一起运算,结果为 decimal。任何有 double 参与的运算,结果都为 double。
默认运算精度是 MathContext.DECIMAL128
,你可以通过修改引擎配置项 Options.MATH_CONTEXT
来改变。
如果你觉的为浮点数添加 M
后缀比较麻烦,希望所有浮点数都解析为 decimal ,可以开启 Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL
选项。
数字类型转换
数字类型在运算的时候,会遵循一定的类型转换规则:
- 单一类型参与的运算,结果仍然为该类型,比如整数和整数相除仍然是整数,double 和 double 运算结果还是 double。
- 多种类型参与的运算,按照下列顺序:
long -> bigint -> decimal -> double
自动提升,比如 long 和 bigint 运算结果为 bigint, long 和 decimal 运算结果为 decimal,任何类型和 double 一起运算结果为 double
你可以通过 long(x)
将一个数字强制转化为 long,这个过程中可能丢失精度,也可以用 double(x)
将一个数字强转为 double 类型。
1 | css复制代码## examples/double.av |
a 和 b 都是 long 类型,他们相除的结果仍然是整数, 1/2
结果为 0,但是当使用 double
函数将 b 强制转为 double 类型,两者的结果就是浮点数了:
1 | css复制代码a/b is 0 |
字符串
在任何语言中,字符串都是最基本的类型,比如 java 里就是 String 类型。AviatorScript 中同样支持字符串,只要以单引号或者双引号括起来的连续字符就是一个完整的字符串对象,例如:
"hello world"
'hello world'
"a"
或者'a'
字符串可以直接通过 println
函数打印。
字符串的长度可以通过 string.length
函数获取:
1 | ini复制代码## examples/string.av |
hello world
11
1 | go复制代码 |
examples/string.av
let a = “hello world”;
let b = ‘AviatorScript’;
println(a);
println(string.length(a));
println(a + ‘,’ + b + 5);
1 | markdown复制代码字符串拼接 `a + ',' + b + 5` 包括了数字 5 和字符串 `','` , 任何类型和字符串相加,都将拼接为字符串,这跟 java 的规则一致。因此上面最后一行代码将打印 `hello world,AviatorScript5` 。 |
examples/escape_string.av
println(‘Dennis’s car’);
println(‘AviatorScript is great.\r\nLet’s try it!’);
1 | r复制代码 |
Dennis’s car
AviatorScript is great.
Let’s try it!
1 | 复制代码 |
println(“Dennis ‘s car”);
1 | shell复制代码 |
let name = “aviator”;
let s = “hello,” + name;
1 | go复制代码 |
examples/string_interpolation.av
let name = “aviator”;
let a = 1;
let b = 2;
let s = “hello, #{name}, #{a} + #{b} = #{a + b}”;
p(s);
1 | ruby复制代码 |
hello, aviator, 1 + 2 = 3
1 | bash复制代码 |
examples/boolean.av
println(“3 > 1 is “ + (3 > 1));
println(“3 >= 1 is “ + (3 >= 1));
println(“3 >= 3 is “ + (3 >= 3));
println(“3 < 1 is “ + (3 < 1));
println(“3 <= 1 is “ + (3 <= 1));
println(“3 <= 3 is “ + (3 <= 3));
println(“3 == 1 is “ + (3 == 1));
println(“3 != 1 is “ + (3 != 1));
1 | 复制代码 |
3 > 1 is true
3 >= 1 is true
3 >= 3 is true
3 < 1 is false
3 <= 1 is false
3 <= 3 is true
3 == 1 is false
3 != 1 is true
1 | xml复制代码 |
本文转载自: 掘金