rust - Clone String to Specific Lifetime -


i'm trying write little command line app in rust , i've hit wall lifetimes.

extern crate clap; use self::clap::{app, arg}; use std::env;  impl<'p> params<'p> {     fn get_username_arg<'r>() -> arg<'r, 'r> {         let mut arg = arg::with_name("username")             .short("u")             .long("username")             .takes_value(true);         match env::var("username") {             ok(username) => {                 // how pass `username` default_value?                 arg.default_value(username)             }             err(e) => arg.required(true),         }     }     // more code below... } 

the problem i'm trying pass username default value method, requires str lifetime of 'r. tried cloning can't figure how tell lifetime of clone going be. tried along following lines:

let cln = (&*username).clone::<'r>(); arg.default_value(username) 

for reason telling me username doesn't live long enough, though shouldn't matter since cloned data.

so question is, how make compile?

edit: i'd add important me signature stays same aside lifetime parameters. don't mind doing expensive operations such cloning make work.

malbarbo has provided solutions, i'd discuss aspects of non-working code.

let's start @ function signature:

fn get_username_arg<'r>() -> arg<'r, 'r> { 

this says "for any lifetime caller of function picks, return arg contains references last long". that's pretty difficult promise uphold, caller request meets 'static lifetime, value lasts longer call main! in fact, way meet obligation of "any lifetime" return 'static.

this sign there going problem. see why can't store value , reference value in same struct?, shows case constructor. many people jump attempting return string along &str, answer might short-circuit avenue well. ^_^

username doesn't live long enough, though shouldn't matter since cloned data.

username has specific lifetime , it's finite. if @ piece of code, it's straight-forward find out lifetime of object: it's scope of block variable lives in without moving. in example, username lives during block that's part of match arm ok(username) => { // }. block exits, value destroyed.

clone in case has signature of <'s>clone() -> &'s str if remove elisions (and reify self) according limited understanding of rust in general.

env::var returns result<string, varerror>, , access ok variant, making username string. string implementation of clone takes &string , returns string. i'm not sure -> &'s str come from.

so if clone clone::<'r>() should force lifetime...

this very common mistake. check out do rust lifetimes influence semantics of compiled program? (and maybe why explicit lifetimes needed in rust?) background information. cannot change lifetime of other rewriting code make referred-to value have larger scope. lifetime syntax reflects how long variable lives, does not control it. there's no (safe) way "force" lifetime.

(&*username).clone has signature mean

if dereference , re-reference string, end &str. &str have lifetime corresponds how long string lives. makes sense because &str pointing string. when string deallocated, &str pointing @ memory no longer in valid state.


Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -