let dir = matches.value_of("work_dir").unwrap().clone(); // this is a &str
let dir: &'static str = Box::leak(Box::new(dir));
// complier complains `matches` does not live long enough, but I already clone it
I need a static str from a variable, I searched it but not so many useful information, can you help me ? thanks!
It is not generally possible to extend lifetimes soundly, and it is usually not necessary, either. What do you need this for? There's likely a better solution.
yes it works when I turned dir to string,thank you very much, I need this otherwise complier would say that it doesn't live long enough in the tokio spawn clousure, and why does string work? not str, would u mind explaining it a little bit?
depends on the use case. My "solution" leaks memory (obviously, as seen in the call to Box::leak). If you happen to keep using the dir value until pretty much the end of your program run that isn't too bad, but if it's a short-lived value, you won't get your memory back.
I'm assuming this is the clap crate (or a wrapper thereof). You're clone()ing a &str which gives you a copy of that &str. You probably wanted .to_string() instead of .clone(). That would make dir a String, which wouldn't have the lifetime limitations. You probably don't need to leak at all.
Note that the leaking version also allocates a String before leaking it. This works (and is sound) because of the relationship between 'static and owned values. As @H2CO3 noted, you can't just extend the lifetime of a reference (e.g. to 'static) and have it work. Thus the round trip through String.
Well if it's read dynamically, then it's certainly not 'static – it only lives as long as you hold onto the presumably owned String that the config parser gives you.
A more principled solution would be to keep your config in one place, and only pass in necessary parts of it locally and explicitly, to whatever functions might need it. Box::leak() is almost always a code smell.