Rất thường xuyên, tôi nhận được Option<String>
từ một phép tính và tôi muốn sử dụng giá trị này hoặc giá trị được mã hóa cứng mặc định.
Điều này sẽ là nhỏ với một số nguyên:
let opt: Option<i32> = Some(3);
let value = opt.unwrap_or(0); // 0 being the default
Nhưng với a String
và a &str
, trình biên dịch phàn nàn về các kiểu không khớp:
let opt: Option<String> = Some("some value".to_owned());
let value = opt.unwrap_or("default string");
Lỗi chính xác ở đây là:
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`
Một tùy chọn là chuyển đổi lát cắt chuỗi thành Chuỗi được sở hữu, như được đề xuất bởi gỉc:
let value = opt.unwrap_or("default string".to_string());
Nhưng điều này gây ra phân bổ, điều này không mong muốn khi tôi muốn ngay lập tức chuyển đổi kết quả trở lại một lát chuỗi, như trong lệnh gọi này tới Regex::new()
:
let rx: Regex = Regex::new(&opt.unwrap_or("default string".to_string()));
Tôi muốn chuyển đổi Option<String>
thành an Option<&str>
để tránh phân bổ này.
Cách viết này là gì?
map
không hoạt động. Tôi không hiểu điều gì xảy ra với bản đầu tiênOptions<String>
và bản sao tham chiếu đến nó trong trường hợpas_deref
biến thể của mã. Đây là mã làm việc của tôi bằng cách sử dụngas_deref
:let device_id = UsbDeviceIdentifier::VidPidSn { vid: device.vendor_id, pid: device.product_id, sn: device.serial_number.as_deref().unwrap_or("") };
và lần thử đầu tiên của tôilet device_id = UsbDeviceIdentifier::VidPidSn { vid: device.vendor_id, pid: device.product_id, sn: device.serial_number.map(|s| s.as_str()).unwrap_or("") };
.