Solidity extension: data type conversion

 

1. Data type implicit conversion (automatic)

Conversion between the same type: from low-length to high-length int8-int16-int32······int256, but int cannot be automatically converted to uint, because it cannot hold negative numbers, so the conversion is not allowed directly, and cannot be converted  int8 into  uint256 ( because  uint256 some values ​​cannot be covered, for example,  -1).

The operands y and z of the addition below do not have the same type, but uint8 can be implicitly converted to uint16, but not vice versa. Therefore, before performing the addition, convert y to the type of z, in type uint16. The result type of the expression y + z is uint16. After performing the addition. Because it is assigned to a variable of type uint32, yet another implicit conversion is performed.

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

2. Data type display conversion (mandatory)        

If the compiler does not support implicit conversion in some cases, but you know exactly what you want to do, you can consider explicit conversion in this case. Note that this may have some unforeseen consequences, so be sure to test to make sure the result is what you want!

1. Convert a  int8 negative number of a type to  uint:

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

At the end of this code, x the value of will be  0xfffff..fd (64 hex characters), since this is the 256-bit complement of -3.

 

2. If a type is explicitly converted to a smaller type, the corresponding high bits will be discarded

uint32 a = 0x12345678;
uint16 b = uint16(a); // the value of b at this time is 0x5678

3. If an integer is explicitly converted to a larger type, it will be padded to the left (i.e. at a higher-order position). The conversion result is still equal to the original integer

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

Fixed-length byte array conversions are different, they can be thought of as a sequence of individual bytes and converting to a smaller type will cut off the sequence

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

1. If the fixed-length byte array is explicitly converted to a larger type, it will be filled in the correct way. Accessing the converted bytes with a fixed index will be equal to the previous value (if the index is still in range):

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

Because integers and fixed-size byte arrays behave differently when truncated (or filled), explicit conversions between integer and fixed-size byte arrays are allowed if they have the same size. To convert between integers and fixed-length byte arrays, an intermediate type must be used to specify the rules for the required truncation and padding:
bytes2 a = 0x1234;
uint32 b = uint16(a); // b is 0x00001234
uint32 c = uint32(bytes4(a)); // c is 0x12340000
uint8 d = uint8(uint16(a)); // d is 0x34
uint8 e = uint8(bytes1(a)); // e is 0x12

3. Conversion of literal constants and basic types

Integer and Literal Constant Conversion

Decimal and hexadecimal literals can be implicitly converted to any integer type large enough to represent it without truncation

uint8 a = 12; // works
uint32 b = 1234; // works
uint16 c = 0x123456; // fail, will be truncated to 0x3456

Fixed-length byte array and literal constant conversion

A decimal literal cannot be implicitly converted to a fixed-length byte array. A hexadecimal literal can be, but only if the hexadecimal number size fits exactly in the fixed-length byte array length. With the exception of the zero value, both decimal and hexadecimal literals of zero can be converted to any fixed-length byte array type:

bytes2 a = 54321; // not feasible
bytes2 b = 0x12; // not feasible
bytes2 c = 0x123; // not feasible
bytes2 d = 0x1234; // works
bytes2 e = 0x0012; // workable
bytes4 f = 0; // works
bytes4 g = 0x0; // works

String literals and hexadecimal string literals can be implicitly converted to fixed-length byte arrays if their number of characters matches the size of the byte type:

bytes2 a = hex "1234"; // works
bytes2 b = "xy"; // works
bytes2 c = hex "12"; // not possible
bytes2 d = hex "123"; // n is not feasible
bytes2 e = "x"; // not possible
bytes2 f = "xyz"; // not possible

4. Data conversion related to address type

  • Correctly sized hexadecimal literals that pass the checksum test are used as  address types. 
  • Only  bytes20 and  uint160 allow explicit conversions to  address types 
  • When converting from  bytes20 or to another integer display  address type, it is treated as  address payable the type. 
  • An address  address a can be  payable(a) converted to  address payable type .

Guess you like

Origin blog.csdn.net/weixin_62421736/article/details/130902603