Sehr oft habe ich eine Option<String>aus einer Berechnung erhalten und möchte entweder diesen Wert oder einen fest codierten Standardwert verwenden.
Dies wäre mit einer ganzen Zahl trivial:
let opt: Option<i32> = Some(3);
let value = opt.unwrap_or(0); // 0 being the default
Aber mit a Stringund a &strbeschwert sich der Compiler über nicht übereinstimmende Typen:
let opt: Option<String> = Some("some value".to_owned());
let value = opt.unwrap_or("default string");
Der genaue Fehler hier ist:
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`
Eine Möglichkeit besteht darin, das String-Slice in einen eigenen String zu konvertieren, wie von rustc vorgeschlagen:
let value = opt.unwrap_or("default string".to_string());
Dies führt jedoch zu einer Zuordnung, die unerwünscht ist, wenn ich das Ergebnis sofort wieder in einen String-Slice konvertieren möchte, wie in diesem Aufruf an Regex::new():
let rx: Regex = Regex::new(&opt.unwrap_or("default string".to_string()));
Ich würde das lieber konvertieren Option<String> , um ein Option<&str>diese Zuordnung zu vermeiden.
Was ist die idomatische Art, dies zu schreiben?
mapnicht funktioniert hat. Ich verstehe nicht, was mit der erstenOptions<String>und der Kopie passiert, die bei deras_derefVariante des Codes darauf verweist . Hier ist mein Arbeitscode mitas_deref:let device_id = UsbDeviceIdentifier::VidPidSn { vid: device.vendor_id, pid: device.product_id, sn: device.serial_number.as_deref().unwrap_or("") };und mein erster Versuchlet device_id = UsbDeviceIdentifier::VidPidSn { vid: device.vendor_id, pid: device.product_id, sn: device.serial_number.map(|s| s.as_str()).unwrap_or("") };.