0

When I want to return an object, I just specify it, but what do I do when the created object is based on a reference of a string? My example:

fn init_keychain() -> keyring::Keyring<'a> {

    // Gets the username of the current user to save it in the right keychain
    let mut username = Command::new("whoami")
                        .output()
                        .expect("Failed to get current user");

    // Check for newline sequence in Command Output and strip it
    if username.stdout[username.stdout.len()-1] == 10 {
        username.stdout.pop();
    }

    let user = String::from_utf8_lossy(&username.stdout);

    // Create a new Keychain attribute to save the passord to
    keyring::Keyring::new("Service", &user.into_owned())
}

Which raises the error:

error: borrowed value does not live long enough
  --> controller.rs:44:44
   |
44 |             keyring::Keyring::new("Service", &user.into_owned())
   |                                              ^^^^^^^^^^^^^^^ does 
not live long enough
...
49 |         }
   |         - temporary value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on 
the body at 30:29...

I understand why the error occurs - the reference &user gets out of scope as soon as init_keychain() ends.

How do I create an object where I need a &str and then return it? Is there some Rusty magic I completely missed? I tried with into_owned() and clone(), but that doesn't change anything about the lifetime of user. So that's where my knowledge ends.

I am confused with Rust's ownership concept, and I can't find information in the docs, Google, or Stack Overflow. But maybe I'm just really bad at figuring this out.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Valentin
  • 3
  • 1
  • TL;DR: You don't and cannot do that. Either your object needs to own the `String` instead of the `&str` or you have to pass the `&str` into the constructor of the object. – Shepmaster Apr 28 '17 at 21:42
  • I read the article you linked and I'm not sure it solves my problem. I wouldn't mind returning an owned String, but since the keyring library only accepts &str as parameter, which is normal behaviour I believe, I have to create a reference somehow, right? So it's not possible to call the function without parameters and still returning the keyring? So I can't create a reference living in the scope of the new object which gets returned instead of the scope of the function it is created in, right? But even then I can't copy the value of the `whoami`, because it too is created in the scope – Valentin Apr 28 '17 at 22:13
  • *So it's not possible to call the function without parameters and still returning the keyring* — that's sounds like you understand completely. `Keyring::new` accepts a `&str` which must be valid and cannot change its memory address while the `Keyring` still exists. – Shepmaster Apr 28 '17 at 22:16
  • Okay, at least I understood the ownership and scope concept better, now. Thank you! I will try to find another solution then – Valentin Apr 28 '17 at 22:24
  • It could be worth asking the crate maintainer if there's a large benefit to keeping the reference. Perhaps the crate could change to store a `String` instead. – Shepmaster Apr 28 '17 at 22:26

0 Answers0