参照型について確認する
コントラクトを記述するときは、参照型についても理解しておく必要があります。
値の独立したコピーを常に渡す値の型とは異なり、参照型の場合はデータの場所を値に提供します。 3 つの参照型は、構造体、配列、マッピングです。
データの場所
参照型を使用する場合は、その型のデータ格納場所を明示的に指定する必要があります。 次のオプションを使用して、型が格納されているデータの場所を指定できます。
memory
:- 関数の引数が保存されている場所
- 有効期間は、外部関数呼び出しの有効期間に制限されています
storage
:- 状態変数が保存されている場所
- 有効期間はコントラクトの有効期間に制限されています
calldata
:- 関数の引数が保存されている場所
- この場所は外部関数のパラメーターには必須ですが、他の変数にも使用できます
- 有効期間は、外部関数呼び出しの有効期間に制限されています
参照型を使用すると、常にデータの独立したコピーが作成されます。
参照型の使用方法の例を次に示します。
contract C {
uint[] x;
// the data location of values is memory
function buy(uint[] memory values) public {
x = values; // copies array to storage
uint[] storage y = x; //data location of y is storage
g(x); // calls g, handing over reference to x
h(x); // calls h, and creates a temporary copy in memory
}
function g(uint[] storage) internal pure {}
function h(uint[] memory) public pure {}
}
配列
配列は、同様のデータをセットのデータ構造に格納する方法です。 配列は固定または動的のいずれかのサイズになります。 それらのインデックスは 0 から始まります。
固定サイズ k
で要素型 T
の配列を作成するには、T[k]
と記述します。 動的にサイズ設定された配列の場合は、T[]
を記述します。
配列の要素は任意の型にすることができます。 たとえば、uint、メモリ、またはバイトを含めることができます。 配列には、マッピングまたは構造体を含めることもできます。
次の例は配列の作成を示しています。
uint[] itemIds; // Declare a dynamically sized array called itemIds
uint[3] prices = [1, 2, 3]; // initialize a fixed size array called prices, with prices 1, 2, and 3
uint[] prices = [1, 2, 3]; // same as above
配列メンバー
次のメンバーを使用すると、配列に関する情報の操作と取得の両方を行うことができます。
- length: 配列の長さを取得します。
- push(): 配列の末尾に要素を追加します。
- pop: 配列の末尾から要素を削除します。
次に例をいくつか示します。
// Create a dynamic byte array
bytes32[] itemNames;
itemNames.push(bytes32("computer")); // adds "computer" to the array
itemNames.length; // 1
構造体
構造体は、ユーザーが実際のオブジェクトを表すために定義できるカスタム型です。 構造体は通常、スキーマとして、またはレコードを表すために使用されます。
構造体宣言の例:
struct Items_Schema {
uint256 _id;
uint256 _price;
string _name;
string _description;
}
マッピングの種類
マッピングは、一緒にカプセル化またはパッケージ化されるキーと値のペアです。 マッピングは、JavaScript のディクショナリまたはオブジェクトに最も近いものです。 通常は、実際のオブジェクトをモデル化し、より高速なデータ参照を実行するためにマッピングを使用します。 この値には構造体などの複合型を含めることができるため、マッピング型は柔軟で人間が読める形式になります。
次のコード例では、構造体 Items_Schema
を使用し、Items_Schema
によって表される項目のリストをディクショナリとして保存しています。 このように、マッピングによってデータベースを模倣しています。
contract Items {
uint256 item_id = 0;
mapping(uint256 => Items_Schema) public items;
struct Items_Schema {
uint256 _id:
uint256 _price:
string _name;
}
function listItem(uint256 memory _price, string memory _name) public {
items[item_id] = Items_Schema(item_id, _price, _name);
item_id += 1;
}
}
Note
マッピング シグネチャ uint256 => Items_Schema
は、キーが符号なしの整数型で、値が Items_Schema
構造体であることを示します。