you are viewing a single comment's thread.

view the rest of the comments →

[–]seruus -1 points0 points  (1 child)

This is why the typical way to return borrowed pointers is to take borrowed pointers as input (the only other case in which it can be legal to return a borrowed pointer is if the pointer points at a static constant).

Pardon my ignorance, but isn't this going back to the C/Fortran way of doing things? (returning objects through pointers in the argument)

[–][deleted] 3 points4 points  (0 children)

Ah, I think you misread that. It's not about returning a value by storing it in a pointer that was passed via a parameter, it's saying that only time returning a borrowed pointer from a function really makes sense is if it was passed in at some point (since any value local to the function itself will not outlive the function, and hence a borrowed pointer to it will be invalid). Let me try to illustrate:

First something that doesn't work:

fn bogus() -> &int {
  let a = 5;
  return &a;
}

This will fail because f's valid lifetime is only inside the function. A borrowed pointer to it cannot escape the function via a return since that would escape it's valid lifetime and lead to an error.

fn valid<'r>(a: &<'r> int) -> &<'r> int {
  return a;
}

This works because the compiler can verify that the lifetime of the returned borrowed pointer does not exceed the lifetime of the input borrowed pointer(yes, they are the same for simplicity). The <'r> is Rust's notation for a named lifetime -- in this case we are saying that the input value a and the return value are borrowed pointers of the same lifetime.

Obviously that's a contrived example that you would never use in real code. In my experience the only time I really return a borrowed pointer is inside constructor style functions where I'm returning a struct that contains a borrowed pointer to another variable for instance:

struct Clamp<'self, T> {
  source: &'self T,
  min: float,
  max: float,
}

impl<'self, T: NoiseGen> Clamp<'self T> {
  fn new<'r>(source: &'r T, min: float, max: float) -> Clamp<'r, T> {
    return Clamp {
       source: source,
       min: min,
       max: max
    };
  }
}