LoginSignup
0
0

More than 5 years have passed since last update.

Rust Tutorial[2版] めも 5章 5.1.構造体-1

Posted at

はじめに

これはあくまでメモなので、基本的にググってわかるようなことは詳しく書きません。
よろしくお願いします。

また、以下のプログラムでは面倒なのでfn main() {}を省略することがあります。
ご承知おきください。

おさらい

前回は2版の4章の4.3に目を通して、以下のことを学びました。

  • スライスの扱い方

以下のリンクで参照できます。
https://qiita.com/task4233/items/5f9e5868ba5cfbc56739

5. 構造体

structまたは、構造体は、意味のあるグループを形成する複数の関連した値をまとめ、名前付けできる独自のデータ型です。

だそうです。

構造体の定義

構造体は以下のlist1のように定義します。

慣習として構造体の1文字目は大文字とされています。
末尾に;は必要ありません。

list1
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

インスタンス化

構造体は以下のlist2のようにインスタンスを生成できます。
こちらはuser1という変数に対する束縛なので、末尾に;が必要です。

list2
let user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

生成されたインスタンスの要素にアクセスにはドット記法を使います。
ドット記法を使用することで、以下のlist3のように値を変更したり参照したりすることができます。
ただし、値を変更する場合はミュータブルにしておく必要があります。

list3
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn main() {
  let mut user1 = User {
      email: String::from("someone@example.com"),
      username: String::from("someusername123"),
      active: true,
     sign_in_count: 1,
  };

  println!("{}", user1.email);
  user1.email = String::from("anotheremail@example.com"); // 値の変更
  println!("{}", user1.email);

// [output]
// someone@example.com
// anotheremail@example.com
}

また、インスタンス化する際にその都度全ての要素を設定するのが面倒な時は、以下のlist4のような関数を作成することで簡潔にインスタンス化できるようになります。

ここで、フィールドと変数名が同名の時は変数名のみで書くこともできます。

list4
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn build_user(email: String, username: String) -> User {
    User {
        // フィールドと変数名が同じなので、
        // email,
        // のみでも可
        email: email,
        // 同様に
        // username,
        // のみでも可
        username: username,
        active: true,
        sign_in_count: 1,
    }
}

fn main() {
  // 以下の宣言と同義
  let mut user1 = build_user(String::from("someone@example.com"), String::from("someusername123"));
  // let mut user1 = User {
  //     email: String::from("someone@example.com"),
  //     username: String::from("someusername123"),
  //     active: true,
  //    sign_in_count: 1,
  //  };

}

他のインスタンスから新たにインスタンスを生成する

以下のlist5のように、他のインスタンスと異なる部分のみを記述することで新たなインスタンスを生成できる。

ここで、..というきほうにより、セットしていないフィールドを明示的に与えられたインスタンスのフィールドと同じ値になるように指定します。

list5
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn main() {
  let mut user1 = User {
      email: String::from("someone@example.com"),
      username: String::from("someusername123"),
      active: true,
     sign_in_count: 1,
  };

  let user2 = User {
    email: String::from("another@example.com"),
    username: String::from("anotherusername567"),
    ..user1
  };
}

タプル構造体

タプル構造体は、以下のlist6のように定義できます。

ここで、ColorPointは3つのi32からできていますが、別の型として認識されることに注意しましょう。

しかし、要素でみればi32なので要素のみを使用すれば問題はありません。

list6
// Color(R, G, B)
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);

let Point(a, b, c) = origin;
let Blue = Color(a, b, 255); // Point型の要素のみ(i32)をとっているのでエラーは起きない

let Color(r, g, b) = Blue;

println!("(r, g, b) = ({}, {}, {})", r, g, b);

// [output]
// (r, g, b) = (0, 0, 255)

おわりに

2版5章5.1では以下のことが書かれていました。

  • 構造体の基礎的な扱い方

記法は違えど、構造体の概念はやはりどの言語でもあまり変わりませんね。
次回は構造体を使用したプログラム例を扱おうと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0