雑なメモ書き

気楽にいきます

Rustの構造体に対する疑問を検証してみた

doc.rust-lang.org

こちらのドキュメントに対する疑問を解消しております。

構造体に初期値が勝手に入るか?

  • ここの構造体の説明で初期値が無いとどうなるか特に言ってない
  • おそらくはエラーになるはずだが
  • どんなメッセージだかは気になる
fn main() {
    #[derive(Debug)]
    struct User {
        username: String,
        email: String,
        sign_in_count: u64,
        active: bool,
    }

    let user1 = User {};
}

missing fieldsと言われてエラーになる

error[E0063]: missing fields `active`, `email`, `sign_in_count` and 1 other field in initializer of `main::User`
  --> src/main.rs:11:17
   |
11 |     let user1 = User {};
   |                 ^^^^ missing `active`, `email`, `sign_in_count` and 1 other field

error: aborting due to previous error

For more information about this error, try `rustc --explain E0063`.

この件でしらべてみたらでてきたstd::default::Defaultを使うといいらしい

www.utam0k.jp

Struct Update Syntaxというものがある

fn main() {
    #[derive(Debug)]
    struct User {
        username: String,
        email: String,
        sign_in_count: u64,
        active: bool,
    }

    let 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
    };

    println!("{:?},{:?}",user1,user2)
}

よくこの構造体を見てほしい

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

Struct Update Syntaxで扱われたデータは基本データ型のみではないだろうか?

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

Struct Update SyntaxにCopyが実装されていないデータ型を渡すとどうなるのか?

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

user2の方へ所有権が移動した為user1が使えなくなり後ろのprintlnで怒られました

error[E0382]: borrow of moved value: `user1`
  --> src/main.rs:24:26
   |
18 |       let user2 = User {
   |  _________________-
19 | |         email: String::from("another@example.com"),
20 | |         //username: String::from("anotherusername567"),
21 | |         ..user1
22 | |     };
   | |_____- value moved here
23 | 
24 |       println!("{:?},{:?}",user1,user2)
   |                            ^^^^^ value borrowed here after partial move
   |
   = note: move occurs because `user1.username` has type `std::string::String`, which does not implement the `Copy` trait