アイテムの集合をグループ化し、そのグループを単位として扱うと便利なことがよくあります。Rustでは、このようなグループを構造体と呼び、各項目を構造体のフィールドと呼びます。構造体は利用可能なフィールドの一般的な集合を定義しますが、構造体の特定の例をインスタンスと呼びます。
さらに、構造体には、フィールドにアクセスするためのメソッドを定義することができます。この場合の構造体そのものをselfと呼びます。メソッドが &mut self を使用する場合、フィールドを変更する、つまりミューテートすることができます。一方、&selfを使用した場合、フィールドは変更できません(immutable)。ミュータビリティを制御することで、borrow-checkerは、Rustで発生する並行処理バグの全クラスが発生しないことを保証することができます。
この演習では、構造体に対して2種類のメソッドを実装します。一つは一般にゲッターと呼ばれるもので、構造体のフィールドを世界に公開し、他の誰にもその値を変更させないものです。Rustでは、これらのメソッドは公開するフィールドの名前を共有します。たとえば、nameという構造体のフィールドを取得するゲッターメソッドがある場合、そのメソッドは単にname()という名前になります。
また、一般にセッターと呼ばれる別のタイプのメソッドも実装することになります。これらは、フィールドの値を変更します。セッターはRustではあまり一般的ではありません。フィールドを自由に変更できるのであれば、パブリックにするのが一般的です。しかし、フィールドの更新に副作用がある場合やアクセス制御には便利です。
構造体には、名前付きフィールドを持つ構造体、タプル構造体、ユニット構造体という3つの種類があります。今回の演習では、最初の種類である名前付きフィールドを持つ構造体について学習します。
構造体は、struct キーワードの後に、構造体が記述する型の名前を大文字で続けて定義します。
struct Item {}
のようになります。 次に、追加の型が構造体のフィールドとして構造体本体に取り込まれ、それぞれ独自の型を持つようになります。
struct Item name: String, weight: f32, worth: u32。 }
最後に、implブロック内の構造体には、メソッドを定義することができます。
impl Item { // Item構造体のインスタンスを初期化し返却 fn new() -> Self { unimplemented!() } }