101

サンプル コントラクトを見ると、配列が「メモリ」を使用してメソッドで宣言されている場合とそうでない場合があります。違いは何ですか?

4

3 に答える 3

127

memoryキーワードがない場合、Solidity はstorageで変数を宣言しようとします。

Lead Solidity dev chriseth: 「ストレージは、仮想構造を持つ大規模な配列と考えることができます... 実行時に変更できない構造であり、コントラクトの状態変数によって決定されます」.

つまり、ストレージの構造は、コントラクト レベルの変数宣言に基づいてコントラクトの作成時に設定され、将来のメソッド呼び出しによって変更することはできません。しかし -- そのストレージの内容は sendTransaction 呼び出しで変更できます。このような呼び出しは「状態」を変更するため、コントラクト レベルの変数は「状態変数」と呼ばれます。したがって、変数 uint8 storagevar; コントラクト レベルで宣言された値は、uint8 (0 ~ 255) の任意の有効な値に変更できますが、uint8 型の値の「スロット」は常に存在します。

関数内でmemoryキーワードなしで変数を宣言すると、solidity は現在コンパイルされているストレージ構造を使用しようとしますが、予期しない結果が生じる可能性があります。memoryは、メソッドの実行時に変数用のスペースのチャンクを作成するように solidity に指示し、そのメソッドで将来使用するためのサイズと構造を保証します。

メモリは契約レベルでは使用できません。メソッドのみ。

「memory キーワードとは何ですか? それは何をしますか?」のエントリを参照してください。よくある質問で。ここに引用します:

イーサリアム仮想マシンには、アイテムを格納できる 3 つの領域があります。

1 つ目は、すべてのコントラクト状態変数が存在する「ストレージ」です。すべてのコントラクトには独自のストレージがあり、関数呼び出し間で永続的であり、使用するのに非常にコストがかかります。

2 つ目は「メモリ」で、一時的な値を保持するために使用されます。(外部) 関数呼び出しの間で消去され、安価に使用できます。

3 つ目はスタックで、小さなローカル変数を保持するために使用されます。ほとんど無料で使用できますが、限られた量の値しか保持できません。

ほとんどすべての型は、使用されるたびにコピーされるため、格納場所を指定できません。

いわゆる格納場所が重要な型は、構造体と配列です。たとえば、関数呼び出しでそのような変数を渡す場合、それらのデータがメモリまたはストレージにとどまることができる場合、それらのデータはコピーされません。つまり、呼び出された関数でコンテンツを変更でき、これらの変更は呼び出し元で引き続き表示されます。

関係する変数のタイプに応じて、保存場所のデフォルトがあります。

  • 状態変数は常にストレージにあります
  • 関数の引数は常にメモリ内にあります
  • デフォルトでは、構造体、配列、またはマッピング タイプの参照ストレージのローカル変数
  • 値型のローカル変数 (つまり、配列、構造体、マッピングのいずれでもない) はスタックに格納されます。
于 2015-11-21T02:50:17.233 に答える