Aus irgendeinem Grund erlaubt die Solidität nicht, Werte in das Speicherarray zu schieben
Member "push" ist im bytes32[]-Speicher außerhalb des Speichers nicht verfügbar.
Hier ist ein Beispielvertragscode:
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public pure returns(uint[]) {
uint[] memory result;
for (uint i = 0; i < n; i++)
if (someCondition(i))
result.push(i);
return result;
}
}
Ich könnte das maximal mögliche Array der Größe zuweisen n
und es dann verkleinern, aber es kann die Leistung beeinträchtigen ( n
könnte in der Größenordnung liegen, 100000
während die endgültige Länge des Ergebnisses ist 0..100
). Könnte zum Beispiel someCondition
sein isPrime
. In diesem Fall haben wir ein großes N (was die Vorabzuweisung eines Arrays unmöglich macht) und eine kleine Liste von resultierenden Primzahlen.
Wie könnte es gemacht werden?
Am Ende habe ich ein Größen-Array vorab zugewiesen n
und es dann verkleinert, sobald ich weiß, dass es die endgültige Länge hat:
function getRange(uint n) public pure returns(uint[]) {
uint tookCount = 0;
uint[] memory result = new uint[](n);
for (uint i = 0; i < n; i++)
if (someCondition(i)) {
result.push(i);
tookCount++;
}
uint[] memory trimmedResult = new uint[](tookCount);
for (uint j = 0; j < trimmedResult.length; j++) {
trimmedResult[j] = result[j];
}
return trimmedResult;
}
Dynamische Arrays sind nur im Speicher verfügbar, nicht im Arbeitsspeicher. In Ihrem Fall ist die Größe des result
Arrays im Voraus bekannt ( n
). Sie können also einfach ein Array mit einer Länge von deklarieren n
. Dann können Sie es mit auffüllen i
, was von 0
bis gehtn - 1
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public pure returns(uint[]) {
uint[] memory result = new uint[](n);
for (uint i = 0; i < n; i++)
result[i] = i;
return result;
}
}
wie ich weiss
push ist nur für Speicher-Arrays, nicht für Speicher-Arrays
aus dem Dokument:
push: Dynamische Speicher-Arrays und Bytes (nicht String) haben eine Member-Funktion namens push, die verwendet werden kann, um ein Element am Ende des Arrays anzuhängen. Die Funktion gibt die neue Länge zurück.
Versuchen
result[j]=keccak256(id);//declare j
Da Sie eine Bedingung in der Iteration haben, werde ich diesen Schlüssel in Henks Antwort hinzufügen:
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public pure returns(unit[] memory result) {
uint j = 0;
for (uint i = 0; i < n; i++)
if (someCondition(i))
result[j] = i;
j++;
}
}
Verwenden Sie Speicherplatz statt Arbeitsspeicher
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public view returns(uint[]) {
uint[] storage result;
for (uint i = 0; i < n; i++)
if (i> 1)
result.push(i);
return result;
}
}
uint[]
der erste Slot nicht leer ist.
Badr Bellaj
Alex Schukowsky
Badr Bellaj
Alex Schukowsky