comment passer par référence?

Oct 04 2020

J'ai quelques questions.

Première:

Donc, dans une fonction, j'ai créé un tableau de mémoire. Je souhaite transmettre cette mémoire par référence à une autre fonction.

function test2() public returns(uint  a) {
        uint[2] memory gio;
        gio[0] = 100;
        gio[1] = 200;
        test3(gio);
        return gio[0];
    }
    
    
    function test3(uint[2] storage arr) private returns (uint) {
        arr[0] = 35;
    }

Cela ne fonctionne pas et dit:

Type d'argument non valide dans l'appel de fonction. Conversion implicite non valide de la mémoire uint256 [2] en pointeur de stockage uint256 [2] demandé. test3 (gio); ^ - ^

N'est-ce pas possible?

Seconde

les fonctions internes et privées sont les seuls types de fonctions qui peuvent recevoir des paramètres comme types de référence, non? puisque les fonctions publiques et externes appelées peuvent dépendre d'une autre application, une autre application ne peut donc pas passer de paramètres comme références. D'accord ?

Troisièmement .

string test;
   
    function test2() public returns(uint  a) {
        test = " awesome ";
        test3(test);
        return 10;
    }
    
    
    function test3(string storage str) private  {
        str = " changed ";
    }

Pourquoi un appel test2entraîne-t-il:

TypeError: Le type literal_string "changed" n'est pas implicitement convertible en pointeur de stockage de chaîne de type attendu. str = "changé"; ^ --------- ^

Réponses

1 Ismael Oct 04 2020 at 06:43

Lorsque vous déclarez un paramètre comme stockage, vous limitez la fonction à n'accepter que les paramètres avec ce qualificatif.

Les qualificatifs storage, memoryet calldatapréciser où se trouvent les données. Vous pouvez convertir implicitement storageen memoryet calldataen memory, mais l'inverse n'est pas possible.

string public stor = "banana";

function test(string calldata calld) external view {
    string memory memo = "pizza";

    foo(memo, stor);
    foo(calld, stor);  // Creates a copy of calld in memory and passes as parameter
    foo(stor, stor);   // Creates a copy of stor in memory and passes as parameter
    
    foo(memo, stor);
    // foo(memo, memo); // Cannot convert from memory to storage
    // foo(memo, calld); // Cannot convert from calldata to storage
}

function foo(string memory, string storage) internal view {
    
}

/* This fails because you can only use calldata on external functions
function bar(string calldata) internal view {
    
} */

Les types de valeur tels que bool, uintXXX, bytesYY, address, etc. sont passés par valeur. Les tyeps sans valeur comme les structures, les tableaux, les chaînes sont passés par référence.

  • Les fonctions qui sont public, internalet privatepeuvent utiliser des types passés par référence , mais seulement si elles sont appel du même contrat.

  • Fonctionne publicet externalrecevra une copie lors de l'appel par un utilisateur régulier d'un autre contrat.

Je ne sais pas pourquoi, mais au moins depuis solc 0.3, ce n'était pas autorisé.