ProgrammingRust開発者 / バックエンド開発者

Rustにおけるコンストラクタとファクトリーメソッド(例えば、new、with_capacity)とは何か、それを正しく実装する方法、初心者にありがちなエラーは何か?

Hintsage AIアシスタントで面接を突破

答え。

RustにはC++やJavaのような特別なコンストラクタがありません。通常、コンストラクタは関連関数(例えば、new)として実装されます。重要な特徴は以下の通りです。

  • 関連関数はトレイトやオブジェクトに結びついておらず、::を使って呼び出されます。
  • selfやResult<Self, E>を返すことができ、エラーが発生する可能性があるコンストラクタに便利です。
  • with_capacityfrom_str、カスタムバリエーションなど、さまざまなファクトリーを実装できます。

基本的なコンストラクタの例は以下の通りです。

struct Point { x: i32, y: i32 } impl Point { pub fn new(x: i32, y: i32) -> Self { Point { x, y } } }

エラーが発生する可能性があるコンストラクタの例は以下の通りです。

impl Point { pub fn try_new(x: i32, y: i32) -> Result<Self, String> { if x < 0 || y < 0 { Err("Coordinates must be non-negative".to_string()) } else { Ok(Point { x, y }) } } }

ひっかけ質問。

コンストラクタには通常の関数、メソッド、または関連関数のどれを使うべきか、その理由は?

多くの人は「メソッド」と答えます。しかしRustではコンストラクタは関連関数のみ(selfなし)でなければなりません。なぜなら、インスタンスがまだ存在しないので通常のメソッドを呼び出すことはできません。

struct Foo; impl Foo { // 関連関数、メソッドではない pub fn new() -> Self { Foo } }

このテーマに関する実際のエラーの例。


物語

プログラマーがメソッドとしてコンストラクタを実装しました:

impl Point { pub fn make(&self, x: i32, y: i32) -> Self { ... } }

これは不合理で混乱を招きます:オブジェクトを作成するためには、まだ存在しないオブジェクトが必要だからです!開発者はこのメソッドをどう呼び出すか迷いました。静的関数に修正されました。


物語

古典的なエラー:警告なしにfallibleコンストラクタのためにOption<Self>を返し、その結果として連鎖的なエラーを見逃すことがありました。Result<Self, E>を返すようにしたことで、エラーをより明示的に表示できるようになりました。


物語

from_partsfrom_strの形式のファクトリーをFrom/FromStrトレイトを使用せずに実装しました。その結果、標準の変換メカニズム(例えば、str.parse::<MyType>())が機能しませんでした。エラーを発見した後、FromStrを導入し、エコシステムのライブラリとの互換性を向上させました。