非常に頻繁に私は Option<String>
計算からありますが、この値またはデフォルトのハードコードされた値のいずれかを使用したいと思います。
これは整数では簡単です。
let opt: Option<i32> = Some(3);
let value = opt.unwrap_or(0); // 0 being the default
しかし、aString
とaを使用すると&str
、コンパイラは型の不一致について文句を言います。
let opt: Option<String> = Some("some value".to_owned());
let value = opt.unwrap_or("default string");
ここでの正確なエラーは次のとおりです。
error[E0308]: mismatched types
--> src/main.rs:4:31
|
4 | let value = opt.unwrap_or("default string");
| ^^^^^^^^^^^^^^^^
| |
| expected struct `std::string::String`, found reference
| help: try using a conversion method: `"default string".to_string()`
|
= note: expected type `std::string::String`
found type `&'static str`
1つのオプションは、rustcによって提案されているように、文字列スライスを所有されている文字列に変換することです。
let value = opt.unwrap_or("default string".to_string());
しかし、これにより割り当てが発生します。これは、次の呼び出しのように、結果をすぐに文字列スライスに変換する場合には望ましくありませんRegex::new()
。
let rx: Regex = Regex::new(&opt.unwrap_or("default string".to_string()));
私はむしろ変換したい Option<String>
Option<&str>
この割り当てを回避するために、をにます。
これを書くための理想的な方法は何ですか?
map
しても機能しなかった理由がわかりません。コードのバリアントのOptions<String>
場合、最初のコピーとそれを参照するコピーがどうなるかわかりませんas_deref
。これがas_deref
:let device_id = UsbDeviceIdentifier::VidPidSn { vid: device.vendor_id, pid: device.product_id, sn: device.serial_number.as_deref().unwrap_or("") };
と私の最初の試みを使用した私の作業コードlet device_id = UsbDeviceIdentifier::VidPidSn { vid: device.vendor_id, pid: device.product_id, sn: device.serial_number.map(|s| s.as_str()).unwrap_or("") };
です。