通常,我是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`
一种选择是将字符串切片转换为拥有的String,如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("") };
。