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
intouint256
( becauseuint256
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 touint
:int8 y = -3; uint x = uint(y);At the end of this code,
x
the value of will be0xfffff..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 0x56783. 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 0x121. 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 0x3456Fixed-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; // worksString 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
anduint160
allow explicit conversions toaddress
types- When converting from
bytes20
or to another integer displayaddress
type, it is treated asaddress payable
the type.- An address
address a
can bepayable(a)
converted toaddress payable
type .