Ich habe ein paar Fragen.
Erste:
Also, in einer Funktion habe ich ein Speicherarray erstellt. Ich möchte diesen Speicher durch Verweis auf eine andere Funktion übergeben.
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;
}
Das geht nicht und sagt:
Ungültiger Typ für Argument im Funktionsaufruf. Ungültige implizite Konvertierung von uint256[2]-Speicher in uint256[2]-Speicherzeiger angefordert. test3(gio); ^-^
Ist es nicht möglich?
Zweite
interne und private Funktionen sind die einzigen Funktionstypen, die Parameter als Referenztypen empfangen können, oder? Da aufgerufene öffentliche und externe Funktionen von einer anderen Anwendung abhängig sein könnten, kann eine andere App keine Parameter als Referenzen übergeben. Einverstanden ?
Drittens .
string test;
function test2() public returns(uint a) {
test = " awesome ";
test3(test);
return 10;
}
function test3(string storage str) private {
str = " changed ";
}
Warum test2
führt ein Anruf zu:
TypeError: Type literal_string "changed" ist nicht implizit in den erwarteten String-Speicherzeiger des Typs konvertierbar. str = "geändert"; ^---------^
Wenn Sie einen Parameter als Speicher deklarieren, beschränken Sie die Funktion darauf, nur Parameter mit diesem Qualifizierer zu akzeptieren.
Die Qualifizierer storage
, memory
und calldata
geben an, wo sich die Daten befinden. Sie können implizit storage
in memory
und calldata
in konvertieren memory
, aber das Gegenteil ist nicht möglich.
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 {
} */
Werttypen wie bool, uintXXX, bytesYY, Adresse usw. werden als Wert übergeben. Nicht-Wert-Typen wie Strukturen, Arrays, Zeichenfolgen werden als Referenz übergeben.
Funktionen, die public
, internal
und sind private
, können Typen verwenden, die als Referenz übergeben werden, aber nur, wenn sie von demselben Vertrag aufgerufen werden.
Funktioniert public
und external
erhält bei Aufruf durch einen regulären Nutzer eine Kopie von einem anderen Vertrag.
Ich weiß nicht warum, aber zumindest seit Solc 0.3 war es nicht erlaubt.
Nika Kuraschwili
Nika Kuraschwili
Ismael
function test(string calldata calld) external view
ohne Vorwarnung.