I'm trying to understand how I would create an API where the user decides whether to pass ownership to the struct, or to pass a reference to the struct. What I came up with is this:
use std::borrow::Cow;
struct Complicated<'a> {
maybe_owned: Cow<'a, str>
}
impl<'a> Complicated<'a> {
fn new(value: Cow<'a, str>) -> Self {
Self{
maybe_owned: value
}
}
fn value(&self) -> &'a str {
self.maybe_owned.as_ref()
}
}
fn main() {
let static_str = "static";
let owned_str = "owned".to_owned();
let complicated_static = Complicated::new(Cow::Borrowed(static_str));
let complicated_owned = Complicated::new(Cow::Owned(owned_str));
println!("{}", complicated_static.value());
println!("{}", complicated_owned.value());
}
It doesn't compile with:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:20:26
|
20 | self.maybe_owned.as_ref()
| ^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 19:5...
--> src/main.rs:19:5
|
19 | / fn value(&self) -> &'a str {
20 | | self.maybe_owned.as_ref()
21 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:20:9
|
20 | self.maybe_owned.as_ref()
| ^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 12:6...
--> src/main.rs:12:6
|
12 | impl<'a> Complicated<'a> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:20:9
|
20 | self.maybe_owned.as_ref()
| ^^^^^^^^^^^^^^^^^^^^^^^^^
In my mind 'a
represents the lifetime of the struct, and any data borrowed by the struct, so it seems like returning &'a str
would indicate that all is well, so long as the returned ref does not outlive the struct, which does not outlive the thing passed in with new
.
I'm either way off, or close. Not sure which. Is this type of interface possible, where the user decides whether to move data into the struct, or to retain ownership (say for performance)?
What would a minimal implementation look like, if so?