Solidity 字面值
字面值(literal)是指在程序中无需变量保存,可直接表示为一个具体的数字或字符串的值。Solidity支持多种字面值类型,包括:
- 地址字面值
- 有理数和整数字面值
- 字符串字面值
- Unicode字面值
我们接下来对它们逐一进行介绍。
地址字面值(address literal)
地址字面值是一个长度为42字节的十六进制字符串。形如 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 就是一个地址字面值。地址字面值可以直接赋值给地址类型:
address addr = 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990;
有理数和整数字面值
Solidity支持多种有理数和整数的字面值表示方式:
- 十进制整数:例如
123 - 十进制小数:例如
.1,1.2等;但是不能是1.因为其限制小数点后面必须至少跟一个数字 - 十六进制整数:例如
0xff - 科学记数法:例如
2e10,-2e10,2e-10,2.5e1
uint256 d1 = 123; // d1=123
uint256 d2 = .1+1.9; // d2=2
uint256 h = 0xff; // h=255
int256 s1 = 2e10; // s1=20000000000
int256 s2 = -2e10; // s2=-20000000000
注意在Solidity中是不支持8进制字面值的,所以不要使用8进制的字面值表示方式。
有时候你会注意到有些合约里面的整数字面值带下划线 _ 。它们仅仅用来做视觉辅助,不会对数值有什么影响。例如 1000_000 是100万。
有理数和整数字面值可以是任意精度
值得一提的是,所有的有理数和整数字面值可以是任意精度,不会有精度损失的问题。例如下面的例子中, p 的值为 1 。虽然其计算过程的中间值 (2**800 + 1) 已经超过了 uint256 可以表示的范围,但是整个表达式的最后结果是 1 。同理再举一例: .5*8 的结果为 4 。
uint256 p = (2**800 + 1) - 2**800;
但是要注意一个规则:只要字面值和非字面值进行了运算,那么字面值就会被尝试转换成非字面值的类型。例如下面这个表达式, 2.5 与 a 进行了运算,所以编译器会尝试将 2.5 转换成 uint128 类型。不过因为类型不匹配,编译器会报错。
uint128 a = 1;
uint128 b = 2.5 + a + 0.5; //编译报错
但是如果你把代码改成下面这个样子你会得到 b=4 的结果。这是因为两个字面值 2.5 + 0.5 先进行了运算,得到 3 ,然后将 3 转换成 uint128 ,再与 a 进行运算,最后得到 4 ;
uint128 a = 1;
uint128 b = 2.5 + 0.5 + a;
再调换一下 a 的位置,编译器也会报错,这是因为 a 和 2.5 先结合运算,所以需要将 2.5 转换成 uint128 ,因为类型不匹配,所以报错。
uint128 a = 1;
uint128 b = a + 2.5 + 0.5 ; //编译报错
字符串字面值
字符串字面值定义
字符串字面值用单引号 ’’ 或者双引号 ”” 定义。如下所示:
string memory s1 = "This is a string"; // 双引号
string memory s2 = 'This is a string'; // 单引号
与C语言不同的是,Solidity的字符串字面值后面不会跟 \0 。例如 ”foo” 是三个字节,而不是四个字节。
隐式类型转换
字符串字面值可以隐式地转换成 bytes1, bytes2, …, bytes32 还有 string 类型。所以可以直接对它们进行赋值。如下所示:
bytes1 b1 = "b";
bytes2 b2 = "b2";
bytes3 b3 = "b3";
bytes32 b32 = "b32";
string memory str = "string";
转义字符
除此之外,字符串字面值还支持下列转义字符:
\<newline>(字符串字面值可以横跨多行)\\(反斜杠)\'(单引号)\"(双引号)\n(新行)\r(回车)\t(tab)\xNN(十六进制表示字符)\uNNNN(unicode表示字符)
这些转义字符可以和其他字符混合使用,例如 ”\’hello world\’” 。
Unicode字面值
Unicode字面值和字符串字面值差不多,只需要在前面加上 unicode 关键字你就可以在里面包含任何的UTF-8字符。Unicode字面值是由反斜杠 \ 和四位十六进制数拼成的。例如, \u0041 表示大写字母 A。同时,你也可以使用Emoji:
string memory a = unicode"Hello \u0041 😃";
小结
- 字面值(literal)是在程序中无需变量保存的值,可以直接表示为数字或字符串。Solidity支持多种字面值类型:地址字面值,有理数和整数字面值,字符串字面值,Unicode字面值。
- 地址字面值是一个长度为42字节的十六进制字符串,可以直接赋值给地址类型。
- 有理数和整数字面值有多种表示方式:十进制整数,十进制小数,十六进制整数,科学记数法。Solidity 不支持8进制字面值。
- 在 Solidity 中,可以在整数字面值中使用下划线
_来增强可读性。例如,1_000_000表示 100万。 - 字符串字面值是由双引号
"或单引号'括起来的字符串。可以使用转义字符\来表示一些特殊字符。 - Unicode字面值是由反斜杠
\和四位十六进制数拼成的。例如,\u0041表示大写字母A。