Menu
Coddy logo textTech

Dropトレイト

CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 56/61。

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

Dropトレイトには、&mut selfを引数に取るdropという名前のメソッドが1つだけあります:

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が自動的に管理できないリソースの解放といったクリーンアップタスクに一般的に使用されます。Dropトレイトは、早期リターンによってスコープが終了した場合でも、クリーンアップコードが実行されることを保証します。

challenge icon

チャレンジ

簡単

自動クリーンアップを実証するリソース管理システムを構築しましょう!ファイルを開いたり閉じたりすることをシミュレートする FileHandle 構造体を作成します。ハンドルがスコープ外に出ると、ファイルが閉じられたことを自動的に通知します。

コードを2つのファイルに分けて構成します:

  • file_handle.rs: 公開された filename フィールド(String)を持つ公開 FileHandle 構造体を定義します。FileHandle を作成し、ファイルが "opened"(開かれた)ときにメッセージを表示する new 関連関数を実装します。次に、ハンドルがドロップされたときに終了メッセージを表示するように Drop トレイトを実装します。
  • main.rs: file_handle モジュールを取り込み、ファイル名を受け取り、ローカルスコープ内で FileHandle を作成し、ファイルが "open"(開いている)間に処理メッセージを表示する process_file という関数を作成します。スコープが終了すると、Drop の実装が自動的に実行されます。提供された入力を使用してこの関数を呼び出します。

FileHandle が作成されるとき、次のように表示する必要があります:

Opening file: {filename}

処理中(スコープ内)は、次のように表示します:

Processing {filename}...

FileHandle がドロップされる(スコープが終了する)とき、次のように表示する必要があります:

Closing file: {filename}

例えば、入力が data.txt の場合:

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

入力が config.json の場合:

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

1つの入力(ファイル名の文字列)を受け取ります。

チートシート

Dropトレイトを使用すると、値がスコープを抜けるときに自動的に実行されるカスタムのクリーンアップコードを定義できます。

Dropトレイトは、&mut selfを引数に取るdropという名前の単一のメソッドを持っています。

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." と表示されます

Dropトレイトは、ファイルハンドルのクローズ、サーバーからの切断、リソースの解放といったクリーンアップタスクによく使用されます。早期リターンによってスコープが終了した場合でも、クリーンアップコードが実行されることを保証します。

自分で試してみよう

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腕試し

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

Object Oriented Programmingのすべてのレッスン