Menu
Coddy logo textTech

Dropトレイト

CoddyのRustジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 56/61。

Rust で値がスコープ外に出ると、automatically クリーンアップされます。しかし、そのタイミングでログの記録、リソースの解放、最後のメッセージの送信など、カスタムコードを実行する必要がある場合はどうすればよいでしょうか? Drop トレイトを使うと、構造体が破棄される直前に何が起こるかを正確に定義できます。

Drop trait には、&mut self を受け取る drop という単一の method があります。

struct Connection {
    id: u32,
}

impl Drop for Connection {
    fn drop(&mut self) {
        println!("Connection {} closed.", self.id);
    }
}

dropを直接呼び出すことはありません。値がスコープ外になると、Rustが自動的に呼び出します。

fn main() {
    let conn = Connection { id: 42 };
    println!("Using connection...");
}  // "Connection 42 closed." がここで自動的に出力されます

出力は次のようになります:

Using connection...
Connection 42 closed.

これは Rust におけるデストラクタのバージョンです。一般的には、ファイルハンドルを閉じる、サーバーとの接続を切断する、Rust が automatically 管理できないリソースを解放するといったクリーンアップ作業に使用されます。Drop トレイトにより、早期リターンによってスコープが終了した場合でも、クリーンアップコードが実行されることが保証されます。

challenge icon

チャレンジ

簡単

自動クリーンアップを実演するリソース管理システムを構築しましょう!file の opening と closing をシミュレートする FileHandle struct を作成します。handle がスコープ外に出ると、file が closed されたことを自動的に通知します。

コードを2つの file に分けて整理します。

  • file_handle.rs: public な FileHandle struct と public な filename field(String)を Define します。FileHandle を Create し、file が「opened」されたときに message を prints する new associated function を Implement します。次に Drop trait を Implement し、handle が dropped されたときに closing message を prints します。
  • main.rs: file_handle module を取り込み、filename を受け取り、local scope Inside に FileHandle を Create し、file が「open」の間に processing message を prints する function called process_file を作成します。Drop の Implement は scope が ends したときに automatically 実行されます。この function を provided input で呼び出します。

FileHandle が Create されたとき、次を prints する必要があります。

Opening file: {filename}

processing 中(scope Inside)には、次を prints します。

Processing {filename}...

FileHandle が dropped されたとき(scope ends)、次を prints する必要があります。

Closing file: {filename}

たとえば、input が data.txt の場合:

Opening file: data.txt
Processing data.txt...
Closing file: data.txt

input が config.json の場合:

Opening file: config.json
Processing config.json...
Closing file: config.json

1つの input、つまり filename string を受け取ります。

REQUIRED OUTPUT FORMAT:

[Your translated content here]

自分で試してみよう

mod file_handle;

use file_handle::FileHandle;

// TODO: process_file 関数を実装する
// 次のようにする必要があります:
// 1. ローカルスコープを作成する(波括弧 {} を使用)
// 2. そのスコープ内で、FileHandle::new() を使用して FileHandle を作成する
// 3. 処理メッセージを出力する: "Processing {filename}..."
// 4. スコープが終了すると、Drop が自動的に呼び出される
fn process_file(filename: &str) {
    // TODO: この関数を実装する
}

fn main() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let filename = input.trim();
    
    process_file(filename);
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rustオンラインコンパイラ