The string is a reference type in Solidity and references are passed by value or copied when specified as any function's argument. Think of objects in Javascript which show no changes in calling function when they are re-assigned in the called function, but any update of its properties does reflect the change. This reference is different from pointers in other languages that can be directly dereferenced with asterisk *
to change the contents at pointed location in memory.
In the first case, the memory
reference is reassigned, hence the change is reflected only local to the function as string's memory
reference was copied. The only changes that are reflected in the calling function are when some property on the received reference is updated (like a property of struct or index of an array), but when a reference is reassigned, it points to a new memory location and the original reference in calling function remains unchanged. string
type does not have any property and neither it can be updated through index but if you utilize bytes
type then you can see the behavior where we are able to update properties on references which in the following case is indexes of array. But if you re-assign bytes
reference then the calling function shows no changes.
contract Test {
function testing() public pure returns (string memory) {
string memory x = "Hello";
callOtherFunction(bytes(x));
return string(x);
}
function callOtherFunction(bytes memory x) internal pure {
x[0] = bytes1('W');
x[1] = bytes1('o');
x[2] = bytes1('r');
x[3] = bytes1('l');
x[4] = bytes1('d');
}
}
The second case is showing the same behavior, the difference is just that the Solidity compiler does not allow reassigning references pointing to contract's storage. Although, you can still update properties on the storage
pointer.
contract Test {
string public state_x = "Hello";
function testingShit() public {
callOtherFunction(bytes(state_x));
}
function callOtherFunction(bytes storage x) internal {
x[0] = bytes1('W');
x[1] = bytes1('o');
x[2] = bytes1('r');
x[3] = bytes1('l');
x[4] = bytes1('d');
}
}