mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #5772 from ethereum/docs-split-conversion
[DOCS] Split conversion sections into new doc
This commit is contained in:
		
						commit
						6d4d0a5308
					
				
							
								
								
									
										128
									
								
								docs/types.rst
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								docs/types.rst
									
									
									
									
									
								
							| @ -83,130 +83,4 @@ each ``_KeyType``, recursively. For example with a mapping: | ||||
| 
 | ||||
| .. include:: types/operators.rst | ||||
| 
 | ||||
| .. index:: ! type;conversion, ! cast | ||||
| 
 | ||||
| .. _types-conversion-elementary-types: | ||||
| 
 | ||||
| Conversions between Elementary Types | ||||
| ==================================== | ||||
| 
 | ||||
| Implicit Conversions | ||||
| -------------------- | ||||
| 
 | ||||
| If an operator is applied to different types, the compiler tries to | ||||
| implicitly convert one of the operands to the type of the other (the same is | ||||
| true for assignments). In general, an implicit conversion between value-types | ||||
| is possible if it | ||||
| makes sense semantically and no information is lost: ``uint8`` is convertible to | ||||
| ``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256`` | ||||
| (because ``uint256`` cannot hold e.g. ``-1``). | ||||
| 
 | ||||
| For more details, please consult the sections about the types themselves. | ||||
| 
 | ||||
| Explicit Conversions | ||||
| -------------------- | ||||
| 
 | ||||
| If the compiler does not allow implicit conversion but you know what you are | ||||
| doing, an explicit type conversion is sometimes possible. Note that this may | ||||
| give you some unexpected behaviour and allows you to bypass some security | ||||
| features of the compiler, so be sure to test that the | ||||
| result is what you want! Take the following example where you are converting | ||||
| a negative ``int8`` to a ``uint``: | ||||
| 
 | ||||
| :: | ||||
| 
 | ||||
|     int8 y = -3; | ||||
|     uint x = uint(y); | ||||
| 
 | ||||
| At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex | ||||
| characters), which is -3 in the two's complement representation of 256 bits. | ||||
| 
 | ||||
| If an integer is explicitly converted to a smaller type, higher-order bits are | ||||
| cut off:: | ||||
| 
 | ||||
|     uint32 a = 0x12345678; | ||||
|     uint16 b = uint16(a); // b will be 0x5678 now | ||||
| 
 | ||||
| If an integer is explicitly converted to a larger type, it is padded on the left (i.e. at the higher order end). | ||||
| The result of the conversion will compare equal to the original integer:: | ||||
| 
 | ||||
|     uint16 a = 0x1234; | ||||
|     uint32 b = uint32(a); // b will be 0x00001234 now | ||||
|     assert(a == b); | ||||
| 
 | ||||
| Fixed-size bytes types behave differently during conversions. They can be thought of as | ||||
| sequences of individual bytes and converting to a smaller type will cut off the | ||||
| sequence:: | ||||
| 
 | ||||
|     bytes2 a = 0x1234; | ||||
|     bytes1 b = bytes1(a); // b will be 0x12 | ||||
| 
 | ||||
| If a fixed-size bytes type is explicitly converted to a larger type, it is padded on | ||||
| the right. Accessing the byte at a fixed index will result in the same value before and | ||||
| after the conversion (if the index is still in range):: | ||||
| 
 | ||||
|     bytes2 a = 0x1234; | ||||
|     bytes4 b = bytes4(a); // b will be 0x12340000 | ||||
|     assert(a[0] == b[0]); | ||||
|     assert(a[1] == b[1]); | ||||
| 
 | ||||
| Since integers and fixed-size byte arrays behave differently when truncating or | ||||
| padding, explicit conversions between integers and fixed-size byte arrays are only allowed, | ||||
| if both have the same size. If you want to convert between integers and fixed-size byte arrays of | ||||
| different size, you have to use intermediate conversions that make the desired truncation and padding | ||||
| rules explicit:: | ||||
| 
 | ||||
|     bytes2 a = 0x1234; | ||||
|     uint32 b = uint16(a); // b will be 0x00001234 | ||||
|     uint32 c = uint32(bytes4(a)); // c will be 0x12340000 | ||||
|     uint8 d = uint8(uint16(a)); // d will be 0x34 | ||||
|     uint8 e = uint8(bytes1(a)); // e will be 0x12 | ||||
| 
 | ||||
| .. _types-conversion-literals: | ||||
| 
 | ||||
| Conversions between Literals and Elementary Types | ||||
| ================================================= | ||||
| 
 | ||||
| Integer Types | ||||
| ------------- | ||||
| 
 | ||||
| Decimal and hexadecimal number literals can be implicitly converted to any integer type | ||||
| that is large enough to represent it without truncation:: | ||||
| 
 | ||||
|     uint8 a = 12; // fine | ||||
|     uint32 b = 1234; // fine | ||||
|     uint16 c = 0x123456; // fails, since it would have to truncate to 0x3456 | ||||
| 
 | ||||
| Fixed-Size Byte Arrays | ||||
| ---------------------- | ||||
| 
 | ||||
| Decimal number literals cannot be implicitly converted to fixed-size byte arrays. Hexadecimal | ||||
| number literals can be, but only if the number of hex digits exactly fits the size of the bytes | ||||
| type. As an exception both decimal and hexadecimal literals which have a value of zero can be | ||||
| converted to any fixed-size bytes type:: | ||||
| 
 | ||||
|     bytes2 a = 54321; // not allowed | ||||
|     bytes2 b = 0x12; // not allowed | ||||
|     bytes2 c = 0x123; // not allowed | ||||
|     bytes2 d = 0x1234; // fine | ||||
|     bytes2 e = 0x0012; // fine | ||||
|     bytes4 f = 0; // fine | ||||
|     bytes4 g = 0x0; // fine | ||||
| 
 | ||||
| String literals and hex string literals can be implicitly converted to fixed-size byte arrays, | ||||
| if their number of characters matches the size of the bytes type:: | ||||
| 
 | ||||
|     bytes2 a = hex"1234"; // fine | ||||
|     bytes2 b = "xy"; // fine | ||||
|     bytes2 c = hex"12"; // not allowed | ||||
|     bytes2 d = hex"123"; // not allowed | ||||
|     bytes2 e = "x"; // not allowed | ||||
|     bytes2 f = "xyz"; // not allowed | ||||
| 
 | ||||
| Addresses | ||||
| --------- | ||||
| 
 | ||||
| As described in :ref:`address_literals`, hex literals of the correct size that pass the checksum | ||||
| test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type. | ||||
| 
 | ||||
| Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``. | ||||
| .. include:: types/conversion.rst | ||||
							
								
								
									
										127
									
								
								docs/types/conversion.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								docs/types/conversion.rst
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,127 @@ | ||||
| .. index:: ! type;conversion, ! cast | ||||
| 
 | ||||
| .. _types-conversion-elementary-types: | ||||
| 
 | ||||
| Conversions between Elementary Types | ||||
| ==================================== | ||||
| 
 | ||||
| Implicit Conversions | ||||
| -------------------- | ||||
| 
 | ||||
| If an operator is applied to different types, the compiler tries to | ||||
| implicitly convert one of the operands to the type of the other (the same is | ||||
| true for assignments). In general, an implicit conversion between value-types | ||||
| is possible if it | ||||
| makes sense semantically and no information is lost: ``uint8`` is convertible to | ||||
| ``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256`` | ||||
| (because ``uint256`` cannot hold e.g. ``-1``). | ||||
| 
 | ||||
| For more details, please consult the sections about the types themselves. | ||||
| 
 | ||||
| Explicit Conversions | ||||
| -------------------- | ||||
| 
 | ||||
| If the compiler does not allow implicit conversion but you know what you are | ||||
| doing, an explicit type conversion is sometimes possible. Note that this may | ||||
| give you some unexpected behaviour and allows you to bypass some security | ||||
| features of the compiler, so be sure to test that the | ||||
| result is what you want! Take the following example where you are converting | ||||
| a negative ``int8`` to a ``uint``: | ||||
| 
 | ||||
| :: | ||||
| 
 | ||||
|     int8 y = -3; | ||||
|     uint x = uint(y); | ||||
| 
 | ||||
| At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex | ||||
| characters), which is -3 in the two's complement representation of 256 bits. | ||||
| 
 | ||||
| If an integer is explicitly converted to a smaller type, higher-order bits are | ||||
| cut off:: | ||||
| 
 | ||||
|     uint32 a = 0x12345678; | ||||
|     uint16 b = uint16(a); // b will be 0x5678 now | ||||
| 
 | ||||
| If an integer is explicitly converted to a larger type, it is padded on the left (i.e. at the higher order end). | ||||
| The result of the conversion will compare equal to the original integer:: | ||||
| 
 | ||||
|     uint16 a = 0x1234; | ||||
|     uint32 b = uint32(a); // b will be 0x00001234 now | ||||
|     assert(a == b); | ||||
| 
 | ||||
| Fixed-size bytes types behave differently during conversions. They can be thought of as | ||||
| sequences of individual bytes and converting to a smaller type will cut off the | ||||
| sequence:: | ||||
| 
 | ||||
|     bytes2 a = 0x1234; | ||||
|     bytes1 b = bytes1(a); // b will be 0x12 | ||||
| 
 | ||||
| If a fixed-size bytes type is explicitly converted to a larger type, it is padded on | ||||
| the right. Accessing the byte at a fixed index will result in the same value before and | ||||
| after the conversion (if the index is still in range):: | ||||
| 
 | ||||
|     bytes2 a = 0x1234; | ||||
|     bytes4 b = bytes4(a); // b will be 0x12340000 | ||||
|     assert(a[0] == b[0]); | ||||
|     assert(a[1] == b[1]); | ||||
| 
 | ||||
| Since integers and fixed-size byte arrays behave differently when truncating or | ||||
| padding, explicit conversions between integers and fixed-size byte arrays are only allowed, | ||||
| if both have the same size. If you want to convert between integers and fixed-size byte arrays of | ||||
| different size, you have to use intermediate conversions that make the desired truncation and padding | ||||
| rules explicit:: | ||||
| 
 | ||||
|     bytes2 a = 0x1234; | ||||
|     uint32 b = uint16(a); // b will be 0x00001234 | ||||
|     uint32 c = uint32(bytes4(a)); // c will be 0x12340000 | ||||
|     uint8 d = uint8(uint16(a)); // d will be 0x34 | ||||
|     uint8 e = uint8(bytes1(a)); // e will be 0x12 | ||||
| 
 | ||||
| .. _types-conversion-literals: | ||||
| 
 | ||||
| Conversions between Literals and Elementary Types | ||||
| ================================================= | ||||
| 
 | ||||
| Integer Types | ||||
| ------------- | ||||
| 
 | ||||
| Decimal and hexadecimal number literals can be implicitly converted to any integer type | ||||
| that is large enough to represent it without truncation:: | ||||
| 
 | ||||
|     uint8 a = 12; // fine | ||||
|     uint32 b = 1234; // fine | ||||
|     uint16 c = 0x123456; // fails, since it would have to truncate to 0x3456 | ||||
| 
 | ||||
| Fixed-Size Byte Arrays | ||||
| ---------------------- | ||||
| 
 | ||||
| Decimal number literals cannot be implicitly converted to fixed-size byte arrays. Hexadecimal | ||||
| number literals can be, but only if the number of hex digits exactly fits the size of the bytes | ||||
| type. As an exception both decimal and hexadecimal literals which have a value of zero can be | ||||
| converted to any fixed-size bytes type:: | ||||
| 
 | ||||
|     bytes2 a = 54321; // not allowed | ||||
|     bytes2 b = 0x12; // not allowed | ||||
|     bytes2 c = 0x123; // not allowed | ||||
|     bytes2 d = 0x1234; // fine | ||||
|     bytes2 e = 0x0012; // fine | ||||
|     bytes4 f = 0; // fine | ||||
|     bytes4 g = 0x0; // fine | ||||
| 
 | ||||
| String literals and hex string literals can be implicitly converted to fixed-size byte arrays, | ||||
| if their number of characters matches the size of the bytes type:: | ||||
| 
 | ||||
|     bytes2 a = hex"1234"; // fine | ||||
|     bytes2 b = "xy"; // fine | ||||
|     bytes2 c = hex"12"; // not allowed | ||||
|     bytes2 d = hex"123"; // not allowed | ||||
|     bytes2 e = "x"; // not allowed | ||||
|     bytes2 f = "xyz"; // not allowed | ||||
| 
 | ||||
| Addresses | ||||
| --------- | ||||
| 
 | ||||
| As described in :ref:`address_literals`, hex literals of the correct size that pass the checksum | ||||
| test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type. | ||||
| 
 | ||||
| Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``. | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user