Rustは、高速で信頼性が高く、生産性の高いシステムプログラミング言語です。メモリ安全性とスレッド安全性を保証しながら、高性能なアプリケーションを構築することができます。
Rustをインストールするには、公式サイトからRustupをダウンロードし、指示に従ってインストールします。以下のコマンドで、Rustのバージョンを確認できます:
$ rustc --version
最初のRustプログラムを作成しましょう。以下のコードをmain.rs
というファイル名で保存します:
fn main() { println!("Hello, World!"); }
コンパイルして実行するには:
$ rustc main.rs $ ./main Hello, World!
Rustでは、デフォルトで変数は不変です。可変にするにはmut
キーワードを使用します:
let x = 5; // 不変 let mut y = 5; // 可変 y = 6; // OK
Rustは静的型付け言語です。主な型には以下があります:
関数はfn
キーワードで定義します:
fn add(x: i32, y: i32) -> i32 { x + y } fn main() { let result = add(5, 3); println!("The result is: {}", result); }
Rustは一般的な制御フロー構文をサポートしています:
// if式 let number = 6; if number % 2 == 0 { println!("偶数です"); } else { println!("奇数です"); } // ループ for i in 0..5 { println!("{}回目", i + 1); } // while let mut n = 0; while n < 5 { println!("{}回目", n + 1); n += 1; }
Rustの特徴的な概念である所有権は、メモリ管理を安全に行うための仕組みです:
fn main() { let s1 = String::from("hello"); let s2 = s1; // s1の所有権がs2に移動 // println!("{}", s1); // エラー:s1は既に無効 println!("{}", s2); // OK }
借用(borrowing)は、所有権を移動せずに一時的に値を参照する方法です。
fn main() { let s1 = String::from("hello"); let len = calculate_length(&s1); println!("The length of '{}' is {}.", s1, len); } fn calculate_length(s: &String) -> usize { s.len() }
可変な借用も可能ですが、同時に1つの可変な借用しか存在できません:
fn main() { let mut s = String::from("hello"); change(&mut s); } fn change(some_string: &mut String) { some_string.push_str(", world"); }
列挙型(enum)は、複数の異なる値を持つ可能性がある型を定義します。
enum Result<T, E> { Ok(T), Err(E), } enum Direction { North, South, East, West, } fn main() { let result: Result<i32, String> = Result::Ok(42); let direction = Direction::North; }
構造体(struct)は、関連するデータをグループ化するためのカスタムデータ型です。
struct Person { name: String, age: u32, } fn main() { let person = Person { name: String::from("Alice"), age: 30, }; println!("{} is {} years old.", person.name, person.age); }
パターンマッチングは、Rustの強力な機能の1つで、データの構造に基づいてコードを分岐させることができます。
enum Coin { Penny, Nickel, Dime, Quarter, } fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, } } fn main() { let coin = Coin::Dime; println!("The value is {} cents", value_in_cents(coin)); let number = Some(7); match number { Some(i) => println!("The value is {}", i), None => println!("There is no value"), } }
Rustは例外を使用せず、Result型とパニックを使用してエラーを処理します。
use std::fs::File; use std::io::ErrorKind; fn main() { let f = File::open("hello.txt"); let f = match f { Ok(file) => file, Err(error) => match error.kind() { ErrorKind::NotFound => match File::create("hello.txt") { Ok(fc) => fc, Err(e) => panic!("Problem creating the file: {:?}", e), }, other_error => { panic!("Problem opening the file: {:?}", other_error) } }, }; }
?
演算子を使用して、エラー処理をより簡潔に書くこともできます:
use std::fs::File; use std::io; use std::io::Read; fn read_username_from_file() -> Result<String, io::Error> { let mut f = File::open("hello.txt")?; let mut s = String::new(); f.read_to_string(&mut s)?; Ok(s) }
モジュールはコードを整理し、再利用性を高めるのに役立ちます。
mod front_of_house { pub mod hosting { pub fn add_to_waitlist() {} } } use crate::front_of_house::hosting; pub fn eat_at_restaurant() { hosting::add_to_waitlist(); }
クレートはRustのコードパッケージです。ライブラリクレートと実行可能クレートの2種類があります。
外部クレートを使用するには、Cargo.toml
ファイルに依存関係を追加します:
[dependencies] rand = "0.8.3"
そして、コードで使用します:
use rand::Rng; fn main() { let secret_number = rand::thread_rng().gen_range(1..101); println!("The secret number is: {}", secret_number); }