0

I would like a function that returns an owned reference to an object, as well as a borrowed reference to some subpart of it, as a convenience. Is there a way to get the lifetimes right for this?

E.g. A simplified example, returning a modified input, and a slice of this modified input:

pub fn foo<'a>(sentence: &str) -> (String, &'a [u8]) {
    let s = format!("{} with some more words", sentence);

    let idx: usize = 4; // placeholder for some "expensive" calculation

    // compute this `r` too, for the caller, as a convenience.
    let r = &s.as_bytes()[0..idx];
    
    (s, r)
}

The lifetimes aren't setup properly (how does one specify a lifetime on String in the output?).

This fails to compile. Is it possible to return a borrowed reference to an owned reference also being returned?

Compilation errors:

error[E0515]: cannot return value referencing local variable `s`
 --> src/main.rs:8:5
  |
6 |     let r = &s.as_bytes()[0..idx];
  |              - `s` is borrowed here
7 |     
8 |     (s, r)
  |     ^^^^^^ returns a value referencing data owned by the current function

error[E0505]: cannot move out of `s` because it is borrowed
 --> src/main.rs:8:6
  |
1 | pub fn foo<'a>(sentence: &str) -> (String, &'a [u8]) {
  |            -- lifetime `'a` defined here
...
6 |     let r = &s.as_bytes()[0..idx];
  |              - borrow of `s` occurs here
7 |     
8 |     (s, r)
  |     -^----
  |     ||
  |     |move out of `s` occurs here
  |     returning this value requires that `s` is borrowed for `'a`

error: aborting due to 2 previous errors

returning this value requires that s is borrowed for 'a

How would one go about specifying that?

init_js
  • 4,143
  • 2
  • 23
  • 53
  • Why do you need that ? Can't you just borrow the returned owned value ? – Psidom Aug 20 '20 at 04:45
  • My example is overly simplistic here perhaps, and doesn't capture how expensive it is to get to the bit of borrowed data. You could also imagine that modularity can get in the way: obtaining a reference to the borrowed data might require calling accessors that are _not_ available to the caller of `foo()`. – init_js Aug 20 '20 at 06:05
  • 1
    Does [this](https://stackoverflow.com/questions/63476492/rust-return-object-and-reference-to-that-object) answer your question? Referencing the entire struct is equivalent to referencing part of it, as long as the part is actually owned by the struct. – L. Riemer Aug 20 '20 at 06:12
  • "Owned references" aren't a thing. For future reference (no pun intended) you could say "owned value", or, if the indirection is important (it doesn't seem to be here), "owning [smart] pointer" – trent Aug 20 '20 at 11:31
  • yes, I meant owned value. – init_js Aug 20 '20 at 21:59

0 Answers0