Solidity拓展:数据类型的转换

1.数据类型隐式转换 (自动)

同一类型之间的转换:由低长度转换为高长度int8-int16-int32······int256,但int不能自动转换成uint,因为放不下负数所以直接不让转换,且 int8 不能转换成 uint256 (因为 uint256 不能涵盖某些值,例如, -1)。

下面加法的操作数 y 和 z 没有相同的类型,但是 uint8 可以被隐式转换为 uint16,相反却不可以。 因此, 在执行加法之前,将 y 转换为 z 的类型, 在 uint16 类型中。 表达式  y + z 的结果类型是 uint16 。 在执行加法之后。 因为它被赋值给 uint32 类型的变量,又进行了另一个隐式转换.

uint8 y;
uint16 z;
uint32 x = y + z;

2.数据类型显示转换(强制)        

如果某些情况下编译器不支持隐式转换,但是你很清楚你要做什么,这种情况可以考虑显式转换。 注意这可能会发生一些无法预料的后果,因此一定要进行测试,确保结果是你想要的!

1.将一个 int8 类型的负数转换成 uint

int8 y = -3;
uint x = uint(y);

这段代码的最后,x 的值将是 0xfffff..fd (64 个 16 进制字符),因为这是 -3 的 256 位补码形式。

2.如果一个类型显式转换成更小的类型,相应的高位将被舍弃

uint32 a = 0x12345678;
uint16 b = uint16(a); // 此时 b 的值是 0x5678

3.如果将整数显式转换为更大的类型,则将填充左侧(即在更高阶的位置)。 转换结果依旧等于原来整数

uint16 a = 0x1234;
uint32 b = uint32(a); // b 为 0x00001234 now
assert(a == b);

定长字节数组转换则有所不同, 他们可以被认为是单个字节的序列和转换为较小的类型将切断序列

bytes2 a = 0x1234;
bytes1 b = bytes1(a); // b 为 0x12

1.如果将定长字节数组显式转换为更大的类型,将按正确的方式填充。 以固定索引访问转换后的字节将在和之前的值相等 (如果索引仍然在范围内):

bytes2 a = 0x1234;
bytes4 b = bytes4(a); // b 为 0x12340000
assert(a[0] == b[0]);
assert(a[1] == b[1]);

因为整数和定长字节数组在截断(或填充)时行为是不同的, 如果整数和定长字节数组有相同的大小,则允许他们之间进行显式转换, 如果要在不同的大小的整数和定长字节数组之间进行转换 ,必须使用一个中间类型来明确进行所需截断和填充的规则:
bytes2 a = 0x1234;
uint32 b = uint16(a); // b 为 0x00001234
uint32 c = uint32(bytes4(a)); // c 为 0x12340000
uint8 d = uint8(uint16(a)); // d 为 0x34
uint8 e = uint8(bytes1(a)); // e 为 0x12

3.字面常量与基本类型的转换

整型与字面常量转换

十进制和十六进制字面常量可以隐式转换为任何足以表示它而不会截断的整数类型

uint8 a = 12; //  可行
uint32 b = 1234; // 可行
uint16 c = 0x123456; // 失败, 会截断为 0x3456

定长字节数组与字面常量转换

十进制字面常量不能隐式转换为定长字节数组。十六进制字面常量可以是,但仅当十六进制数字大小完全符合定长字节数组长度。 不过零值例外,零的十进制和十六进制字面常量都可以转换为任何定长字节数组类型:

bytes2 a = 54321; // 不可行
bytes2 b = 0x12; // 不可行
bytes2 c = 0x123; // 不可行
bytes2 d = 0x1234; // 可行
bytes2 e = 0x0012; // 可行
bytes4 f = 0; // 可行
bytes4 g = 0x0; // 可行

字符串字面常量和十六进制字符串字面常量可以隐式转换为定长字节数组,如果它们的字符数与字节类型的大小相匹配:

bytes2 a = hex"1234"; // 可行
bytes2 b = "xy"; // 可行
bytes2 c = hex"12"; // 不可行
bytes2 d = hex"123"; // n不可行
bytes2 e = "x"; // 不可行
bytes2 f = "xyz"; // 不可行

4.有关地址类型的数据转换

  • 通过校验和测试的正确大小的十六进制字面常量会作为 address 类型。 
  • 只有 bytes20 和 uint160 允许显式转换为 address 类型 
  • 从 bytes20 或其他整型显示转换为 address 类型时,都会作为 address payable 类型。 
  • 一个地址 address a 可以通过 payable(a) 转换为 address payable 类型.

猜你喜欢

转载自blog.csdn.net/weixin_62421736/article/details/130902603
今日推荐