Rust 学習#
基礎#
-
変数#
let a = 10; // aは不変 let mut a = 10 // aは可変
Rust では、変数がスコープを離れると自動的にメモリが解放され、Rust は末尾の } で自動的に drop を呼び出します。
-
基本型#
2.1 数値型#
文:具体的な操作で、戻り値はありません。
式:式は常に戻り値を返します。
fn add_with_extra(x: i32, y: i32) -> i32 { let x = x + 1; // 文 let y = y + 5; // 文 x + y // 式 }
2.2 文字、ブール、単位型#
String 型:動的文字列型で、ヒープに割り当てられます。
let mut s = String::from("hello"); s.push_str(", world!") // 文字列にリテラルを追加
Rust の文字は Unicode 型であるため、各文字は 4 バイトを占めます。
文字列は UTF-8 エンコーディングで、文字列内の文字が占めるバイト数は変動します(1-4)。
-
追加(Push)
let mut s = String::from("Hello ") s.push_str("rust") s.push('!')
push ():文字を追加します。
push_str ():文字列を追加します。
これらのメソッドは元の文字列に追加し、新しい文字列を返さないため、その文字列は可変でなければなりません。mut キーワードで修飾される必要があります。
-
挿入(Insert)
let mut s = String::from("Hello rust!") s.insert(5, ',') s.insert_str(6, " I like")
文字列の挿入操作は元の文字列を変更するため、その文字列は可変でなければなりません。mut キーワードで修飾される必要があります。
-
置換(Replace)
replace
let string_replace = String::from("I like rust") let new_string = string_replace.replace("rust", "Rust")
replacen
let s_replace = "I like rust learn rust" let ns_replacen = s_replace.replacen("rust", "Rust", 1)
文字列の置換操作は新しい文字列を返す必要があり、元の文字列を操作しません。
replace_range:String 型のみを使用します。
let mut s_replace_range = String::from("I like rust") s_replace_range.replace_range(7..8, "R")
このメソッドは元の文字列を直接操作し、新しい文字列を返さず、mut キーワードで修飾される必要があります。
-
削除(Delete)
pop:最後の文字を削除して返します。
let mut s_pop = String::from("rust pop 中文!") let p1 = s_pop.pop()
このメソッドは元の文字列を直接操作しますが、戻り値があります。文字列が空の場合は None を返します。
remove:指定した位置の文字を削除して返します。
let mut s_remove = String::from("rust remove 中文") string_remove.remove(0)
このメソッドは元の文字列を直接操作しますが、文字列があります。
truncate:指定した位置から末尾までのすべての文字を削除します。
let mut s_truncate = String::from("テストtruncate") s_truncate.truncate(3)
このメソッドは元の文字列を操作し、戻り値はありません。
clear:文字列を空にします。
let mut s_clear = String::from("string clear") s_clear.clear()
このメソッドは元の文字列を直接操作し、s_clear.truncate (0) と同等です。
-
連結(Concatenate)
+ または += を使用して文字列を連結します。右側の引数は文字列のスライス参照 (Slice) 型である必要があります。
+ は新しい文字列を返すため、変数宣言は mut キーワードで修飾する必要はありません。
2.3 タプル#
let x : (i32, f64, u8) = (500, 6.4, 1); let a = x.0; let b = x.1;
2.4 構造体#
- インスタンスを初期化する際、各フィールドを初期化する必要があります。
- フィールドの初期化順序は定義時と一致する必要はありません。
- 関数の引数と構造体のフィールドが同名の場合、略記法で初期化できます。
- user2 は email のみが user1 と異なるため、email に値を割り当て、残りは..user1 で行います。
fn build_user(email: String, username: String) -> User { User { email, username, active: true, sign_in_count: 1, } }
let user2 = User { email: String::from("[email protected]") ..user1 };
単位構造体:この型の内容には関心がなく、その動作にのみ関心があります。
struct AlwaysEqual; let subject = AlwaysEqual; impl SomeTrait for AlwaysEqual {}
構造体の出力印刷
- Display、Debug を手動で実装する。
- 派生クラスを使用する。
#[derive(Debug)] struct Rectangle { width: u32, height: u32, } println!("rect1 is {:?}", rect1)
2.5 所有権と借用#
- Rust では、各値は変数によって所有され、その変数は値の所有者と呼ばれます。
- 一つの値は同時に一つの変数によってのみ所有されるか、つまり一つの値は一つの所有者しか持てません。
- 所有者(変数)がスコープを離れると、その値は破棄され、Rust は自動的に drop 関数を呼び出して変数のヒープメモリをクリーンアップします。
let s1 = String::from("hello"); let s2 = s1; println!("{}, world!", s1)
s1 が s2 に割り当てられた後、Rust は s1 がもはや有効でないと見なすため、s1 がスコープを離れた後に何もドロップする必要はありません。これは所有権が s1 から s2 に移転されたことを意味し、s1 は s2 に割り当てられた後すぐに無効になります。Rust は無効な参照の使用を禁止します。
let x = 5; let y = x;
最初に 5 が変数 x にバインドされ、次に x の値が y にコピーされ、最終的に x と y は両方とも 5 になります。整数は Rust の基本データ型であり、固定サイズの単純な値であるため、これらの値は自動的にコピーされ、スタックに保存され、ヒープにメモリを割り当てる必要はありません。
2.6 参照と借用#
変数の参照を取得することを借用と呼びます。
-
不可変参照
fn main() { let s1 = String::from("hello"); let len = calculate_len(&s1); println!("'{}'の長さは{}です。", s1, len); } fn calculate_len(s: &String) -> usize { s.len() }
-
可変参照
fn main() { let mut s = String::from("hello"); change(&mut s); } fn change(some_string: &mut String) { some_string.push_str(", world"); }
- 不可変参照は同時に複数存在することができます。
- 可変参照は同時に一つだけ存在できます。
- 可変参照と不可変参照は同時に存在できません。
-