Rustの構造体に対する疑問を検証してみた
こちらのドキュメントに対する疑問を解消しております。
構造体に初期値が勝手に入るか?
- ここの構造体の説明で初期値が無いとどうなるか特に言ってない
- おそらくはエラーになるはずだが
- どんなメッセージだかは気になる
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を使うといいらしい
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
GDB Documentationを読んで見る
- GDBのドキュメントを頭からやっていこうかなという感じです
TOP Pageには何が書いてあるか
概ね以下のような内容です。
- 印刷版の紹介
- オンラインマニュアル
- 内部マニュアル
- その他参考資料
オンラインマニュアル
呼び出し方
- ここに普段は使わないであろうオプションが見られます
shellコマンドの使用方法
- 以下のように実行したいコマンドを
- shellの後ろで打ちます
shell ls
ログの出力
ロギングを有効・無効
set logging on|off
ログファイルの名前を変更
set logging file file
debug出力の切り替え
set logging redirect [on|off] set logging debugredirect [on|off]
現在の設定値を表示
show logging
コマンド
プログラムを実行
プログラムの開始
run
引数指定
set args
引数の確認
show args
あとで続きを書きます。
fuzzy finderであるfzfを導入して楽しく検索してみる
- 最近fuzzy finderというものがあります
- いや、前からあったかもしれない
fzfというfuzzy finder
使い方
- Ctrl + r
- 基本これで立ち上がるはず
- 候補になるコマンドの履歴が表示される
- さらにそこから絞り込みが出来る
Rustのリテラル文字列はどういう扱いなのか?
参考
変な現象に遭遇する
- まあ結果的に変じゃないんですけど
- リテラルの文字列を扱うとエラーにならない
- 所有権がmoveした物を使用したらこんぱいるできないんじゃないの?
fn main() { let s = "hello"; let s2 = s; println!("{},{}",s,s2); }
cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.19s Running `target/debug/hello` hello,hello
想定していた動作
fn main() { let s = String::from("hello"); let s2 = s; println!("{},{}",s,s2); }
- これですよこのエラーが出るのを期待していたんですよ
cargo run Compiling hello v0.1.0 (/data) error[E0382]: borrow of moved value: `s` --> src/main.rs:4:22 | 2 | let s = String::from("hello"); | - move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait 3 | let s2 = s; | - value moved here 4 | println!("{},{}",s,s2); | ^ value borrowed here after move error: aborting due to previous error For more information about this error, try `rustc --explain E0382`. error: could not compile `hello`. To learn more, run the command again with --verbose.
そもそもの理解
いま起きてて困っていること
- Stringとstrが同一の挙動をすると思っていたら
- strの方は所有権が移動せずエラーにならない
そして気づいた
前者の文字列
後者の文字列
つまりこういうこと
objdumpのソースコードがUbuntuで欲しい
所属パッケージを探す
dpkg -S objdump zsh-common: /usr/share/zsh/functions/Completion/Unix/_objdump binutils-common:amd64: /usr/share/man/man1/objdump.1.gz binutils-x86-64-linux-gnu: /usr/share/man/man1/x86_64-linux-gnu-objdump.1.gz binutils-x86-64-linux-gnu: /usr/bin/x86_64-linux-gnu-objdump binutils: /usr/bin/objdump
所属パッケージのコードを落とす
apt source binutils
rustで所有権ぽいやつをコードで追ってみる
所有権の説明
- 本家を読むと出てくる
- 以下の3つのルールが気になる訳です
Each value in Rust has a variable that’s called its owner. There can only be one owner at a time. When the owner goes out of scope, the value will be dropped.
- 所有権という変数を保持しているという話になる
- それぽいやつをコードを追うときに見てるので
- 追ってみる
実行
簡単なプログラムを起動する
1 fn main() { 2 let mut s = String::from("hello"); 3 s.push_str(", world"); 4 println!("{}",s); 5 }
String::fromへstepin
- 早速
to_owned
というメソッドが出てきています。
2228 impl From<&str> for String { 2229 #[inline] 2230 fn from(s: &str) -> String { 2231 s.to_owned() 2232 } 2233 }
- このメソッドは以下です
Some types make it possible to go from borrowed to owned, usually by implementing the Clone trait. But Clone works only for going from &T to T. The ToOwned trait generalizes Clone to construct owned data from any borrow of a given type. Creates owned data from borrowed data, usually by cloning.
- 内容的には特定の借用のときに使うぽい
202 #[stable(feature = "rust1", since = "1.0.0")] 203 impl ToOwned for str { 204 type Owned = String; 205 #[inline] 206 fn to_owned(&self) -> String { 207 unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } 208 } 209 210 fn clone_into(&self, target: &mut String) { 211 let mut b = mem::take(target).into_bytes(); 212 self.as_bytes().clone_into(&mut b); 213 *target = unsafe { String::from_utf8_unchecked(b) } 214 } 215 }
- このケースは明示的に書く必要があるんだろうな。
- 後でまた戻ってくる。