0

I have a Message<'a> which has &'a str references on a mostly short-lived buffer. Those references mandate a specific program flow as they are guaranteed to never outlive the lifetime 'a of the buffer.

Now I also want to have an owned version of Message, such that it can be moved around, sent via threads, etc.

Is there an idiomatic way to achieve this? I thought that Cow<'a, str> might help, but unfortunately, Cow does not magically allocate in case &'a str would outlive the buffer's lifetime.

AFAIK, Cow is not special in the sense that no matter if Cow holds an Owned variant, it must still pass the borrow checker on 'a.

Definition of std::borrow::Cow.

pub enum Cow<'a, B> {
    Borrowed(&'a B),
    Owned(<B as ToOwned>::Owned),
}

Is there an idiomatic way to have an owned variant of Message? For some reason we have &str and String, &[u8] and Vec<u8>, ... does that mean people generally would go for &msg and Message?

I suppose I still have to think about if an owned variant is really, really needed, but my experience shows that having an escape hatch for owned variants generally improves prototyping speed.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
duesee
  • 141
  • 1
  • 9
  • You can create a longer-lived `Cow` from a shorter-lived one: `let cow: Cow<'static, _> = Cow::Owned(cow.into_owned())`. – Frxstrem Mar 30 '20 at 16:29
  • 1
    Would it work to make the string type itself a parameter to `Message`, so you could simply use `Message<&str>` most of the time, and `Message` when that won't do? – trent Mar 30 '20 at 17:37
  • 1
    @trentcl I think that's a reasonable solution for their problem, but there's still two separate types in the end ;-) – Shepmaster Mar 30 '20 at 19:31

1 Answers1

3

Yes, you need to have multiple types, one representing the owned concept and one representing the borrowed concept.

You'll see the same technique throughout the standard library and third-party crates.

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366