をとる関数に渡す変数をインスタンス化したいと思いますT: Write
。これは次のように定義されます。
let outputFile = match matches.opt_str("o") {
Some(fileName) => File::create(fileName).expect("could not open output file"),
None => std::io::stdout()
};
現在、コンパイラーは、arms(File
vs Stdout
。)のタイプが一致しないことについて文句を言います。私が欲しいのはoutputFile
、Write
トレイトから任意のメソッドを呼び出すことができるものとして宣言することだけです。
Rustでこれを実行できますか、それともこのmatch
式全体をパラメーターとしてその関数に渡す必要がありますか?
トレイトを実装する2つ(またはそれ以上)の別々のタイプの1つを返したい場合は、トレイトオブジェクトを返す必要があります。
この場合、オブジェクトを所有するために戻り値が必要です(そうしないと、File
が終了する前に破棄されるmatch
ため)。したがって、を使用するのが理にかなっていますBox<dyn Write>
。&Write
およびなどのトレイトオブジェクトBox<dyn Write>
は「ファット」ポインタであり、構造体(File
またはStdout
この場合)へのポインタと、実装方法を説明するvtableへのポインタの両方が含まれWrite
ます。重要なのはBox<dyn Write>
、&Write
自動的にを実装することWrite
です。
これが作業バージョン(遊び場)です:
fn get_writer(f: Option<&str>) -> Box<dyn Write> {
match f {
Some(file_name) => Box::new(File::create(file_name).expect("could not open output file")),
None => Box::new(std::io::stdout()),
}
}
私はあなたのコードからいくつかの変更を加えました:
Box<dyn Write>
戻り値を追加しました(関数がないと、必要になる場合がありますlet outputFile: Box<dyn Write> = ...
。型がどこかに定義されていないと、コンパイラは2つの型を共通に強制変換する必要があると推測できませんBox<dyn Write>
。コンパイラが必要Box<dyn Write>
であることがわかると、できる強要Box<File>
しますBox<dyn Write>
。
2つの結果を囲みました。
Rustの規則に一致fileName
するfile_name
ように名前が変更されました(そして警告を消します)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加