mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Update reference types (1).
This commit is contained in:
		
							parent
							
								
									197875c97a
								
							
						
					
					
						commit
						a8598a774a
					
				| @ -11,7 +11,8 @@ a variable of value type is used. Because of that, reference types have to be ha | |||||||
| more carefully than value types. Currently, reference types comprise structs, | more carefully than value types. Currently, reference types comprise structs, | ||||||
| arrays and mappings. If you use a reference type, you always have to explicitly | arrays and mappings. If you use a reference type, you always have to explicitly | ||||||
| provide the data area where the type is stored: ``memory`` (whose lifetime is limited | provide the data area where the type is stored: ``memory`` (whose lifetime is limited | ||||||
| to a function call), ``storage`` (the location where the state variables are stored) | to an external function call), ``storage`` (the location where the state variables | ||||||
|  | are stored, where the lifetime is limited to the lifetime of a contract) | ||||||
| or ``calldata`` (special data location that contains the function arguments, | or ``calldata`` (special data location that contains the function arguments, | ||||||
| only available for external function call parameters). | only available for external function call parameters). | ||||||
| 
 | 
 | ||||||
| @ -23,7 +24,7 @@ while assignments inside the same data location only copy in some cases for stor | |||||||
| Data location | Data location | ||||||
| ------------- | ------------- | ||||||
| 
 | 
 | ||||||
| Every reference type, i.e. *arrays* and *structs*, has an additional | Every reference type has an additional | ||||||
| annotation, the "data location", about where it is stored. There are three data locations: | annotation, the "data location", about where it is stored. There are three data locations: | ||||||
| ``memory``, ``storage`` and ``calldata``. Calldata is only valid for parameters of external contract | ``memory``, ``storage`` and ``calldata``. Calldata is only valid for parameters of external contract | ||||||
| functions and is required for this type of parameter. Calldata is a non-modifiable, | functions and is required for this type of parameter. Calldata is a non-modifiable, | ||||||
| @ -42,19 +43,29 @@ Data location and assignment behaviour | |||||||
| 
 | 
 | ||||||
| Data locations are not only relevant for persistency of data, but also for the semantics of assignments: | Data locations are not only relevant for persistency of data, but also for the semantics of assignments: | ||||||
| 
 | 
 | ||||||
| * Assignments between ``storage`` and ``memory`` (or from ``calldata``) always create an independent copy. | * Assignments between ``storage`` and ``memory`` (or from ``calldata``) | ||||||
| * Assignments from ``memory`` to ``memory`` only create references. This means that changes to one memory variable are also visible in all other memory variables that refer to the same data. |   always create an independent copy. | ||||||
| * Assignments from ``storage`` to a local storage variable also only assign a reference. | * Assignments from ``memory`` to ``memory`` only create references. This means | ||||||
| * All other assignments to ``storage`` always copy. Examples for this case are assignments to state variables or to members of local variables of storage struct type, even if the local variable itself is just a reference. |   that changes to one memory variable are also visible in all other memory | ||||||
|  |   variables that refer to the same data. | ||||||
|  | * Assignments from ``storage`` to a **local** storage variable also only | ||||||
|  |   assign a reference. | ||||||
|  | * All other assignments to ``storage`` always copy. Examples for this | ||||||
|  |   case are assignments to state variables or to members of local | ||||||
|  |   variables of storage struct type, even if the local variable | ||||||
|  |   itself is just a reference. | ||||||
| 
 | 
 | ||||||
| :: | :: | ||||||
| 
 | 
 | ||||||
|     pragma solidity >=0.4.0 <0.7.0; |     pragma solidity >=0.4.0 <0.7.0; | ||||||
| 
 | 
 | ||||||
|     contract C { |     contract C { | ||||||
|         uint[] x; // the data location of x is storage |         // The data location of x is storage. | ||||||
|  |         // This is the only place where the | ||||||
|  |         // data location can be omitted. | ||||||
|  |         uint[] x; | ||||||
| 
 | 
 | ||||||
|         // the data location of memoryArray is memory |         // The data location of memoryArray is memory. | ||||||
|         function f(uint[] memory memoryArray) public { |         function f(uint[] memory memoryArray) public { | ||||||
|             x = memoryArray; // works, copies the whole array to storage |             x = memoryArray; // works, copies the whole array to storage | ||||||
|             uint[] storage y = x; // works, assigns a pointer, data location of y is storage |             uint[] storage y = x; // works, assigns a pointer, data location of y is storage | ||||||
| @ -96,7 +107,7 @@ as C. | |||||||
| Indices are zero-based, and access is in the opposite direction of the | Indices are zero-based, and access is in the opposite direction of the | ||||||
| declaration. | declaration. | ||||||
| 
 | 
 | ||||||
| For example, if you have a variable ``uint[][5] x memory``, you access the | For example, if you have a variable ``uint[][5] memory x``, you access the | ||||||
| second ``uint`` in the third dynamic array using ``x[2][1]``, and to access the | second ``uint`` in the third dynamic array using ``x[2][1]``, and to access the | ||||||
| third dynamic array, use ``x[2]``. Again, | third dynamic array, use ``x[2]``. Again, | ||||||
| if you have an array ``T[5] a`` for a type ``T`` that can also be an array, | if you have an array ``T[5] a`` for a type ``T`` that can also be an array, | ||||||
| @ -122,9 +133,11 @@ length or index access. | |||||||
| 
 | 
 | ||||||
| Solidity does not have string manipulation functions, but there are | Solidity does not have string manipulation functions, but there are | ||||||
| third-party string libraries. You can also compare two strings by their keccak256-hash using | third-party string libraries. You can also compare two strings by their keccak256-hash using | ||||||
| ``keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))`` and concatenate two strings using ``abi.encodePacked(s1, s2)``. | ``keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))`` and | ||||||
|  | concatenate two strings using ``abi.encodePacked(s1, s2)``. | ||||||
| 
 | 
 | ||||||
| You should use ``bytes`` over ``byte[]`` because it is cheaper, since ``byte[]`` adds 31 padding bytes between the elements. As a general rule, | You should use ``bytes`` over ``byte[]`` because it is cheaper, | ||||||
|  | since ``byte[]`` adds 31 padding bytes between the elements. As a general rule, | ||||||
| use ``bytes`` for arbitrary-length raw byte data and ``string`` for arbitrary-length | use ``bytes`` for arbitrary-length raw byte data and ``string`` for arbitrary-length | ||||||
| string (UTF-8) data. If you can limit the length to a certain number of bytes, | string (UTF-8) data. If you can limit the length to a certain number of bytes, | ||||||
| always use one of the value types ``bytes1`` to ``bytes32`` because they are much cheaper. | always use one of the value types ``bytes1`` to ``bytes32`` because they are much cheaper. | ||||||
| @ -140,9 +153,10 @@ always use one of the value types ``bytes1`` to ``bytes32`` because they are muc | |||||||
| Allocating Memory Arrays | Allocating Memory Arrays | ||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||
| 
 | 
 | ||||||
| You must use the ``new`` keyword to create arrays with a runtime-dependent length in memory. | Memory arrays with dynamic length can be created using the ``new`` operator. | ||||||
| As opposed to storage arrays, it is **not** possible to resize memory arrays (e.g. by assigning to | As opposed to storage arrays, it is **not** possible to resize memory arrays (e.g. | ||||||
| the ``.length`` member). You either have to calculate the required size in advance | the ``.push`` member functions are not available). | ||||||
|  | You either have to calculate the required size in advance | ||||||
| or create a new memory array and copy every element. | or create a new memory array and copy every element. | ||||||
| 
 | 
 | ||||||
| :: | :: | ||||||
| @ -172,7 +186,9 @@ type of the array. | |||||||
| Array literals are always statically-sized memory arrays. | Array literals are always statically-sized memory arrays. | ||||||
| 
 | 
 | ||||||
| In the example below, the type of ``[1, 2, 3]`` is | In the example below, the type of ``[1, 2, 3]`` is | ||||||
| ``uint8[3] memory``. Because the type of each of these constants is ``uint8``, if you want the result to be a ``uint[3] memory`` type, you need to convert the first element to ``uint``. | ``uint8[3] memory``. Because the type of each of these constants is ``uint8``, if | ||||||
|  | you want the result to be a ``uint[3] memory`` type, you need to convert | ||||||
|  | the first element to ``uint``. | ||||||
| 
 | 
 | ||||||
| :: | :: | ||||||
| 
 | 
 | ||||||
| @ -187,7 +203,8 @@ In the example below, the type of ``[1, 2, 3]`` is | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| Fixed size memory arrays cannot be assigned to dynamically-sized memory arrays, i.e. the following is not possible: | Fixed size memory arrays cannot be assigned to dynamically-sized | ||||||
|  | memory arrays, i.e. the following is not possible: | ||||||
| 
 | 
 | ||||||
| :: | :: | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user