Programatically create slice of string slices on Rust [duplicate] - rust

This question already has answers here:
Convert Vec<String> into a slice of &str in Rust?
(2 answers)
How do I get a slice of a Vec<T> in Rust?
(2 answers)
borrowed value does not live long enough in loop
(2 answers)
Closed 2 years ago.
There's an object that only accepts &[&str] as input, but I need to generate this list dynamically. I tried many ways but I always get errors.
My code:
use std::fs;
fn example() {
let paths = fs::read_dir("./").unwrap();
let mut input_files = Vec::<&str>::new();
for path in paths {
let x = ["../", path.unwrap().path().to_str().unwrap()]
.concat()
.as_str();
input_files.push(x);
}
}
Error:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:8:17
|
8 | let x = ["../", path.unwrap().path().to_str().unwrap()]
| _________________^
9 | | .concat()
| |_____________________^ creates a temporary which is freed while still in use
10 | .as_str();
| - temporary value is freed at the end of this statement
11 | input_files.push(x);
| - borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
I think the error is because concat creates a temporary, but why? Why can it not return a string and how should I fix this?
I can't use String.

Related

I don't know why i can't use format! inside for loop on vector [duplicate]

This question already has answers here:
What are the differences between Rust's `String` and `str`?
(14 answers)
Closed 1 year ago.
Compiler says there's temporary value that ends lifetime but i don't know how to prevent this.
fn connectPesel(Names: &mut Vec<&str>){
let mut rng = rand::thread_rng();
for i in 0..Names.len(){
Names[i] = format!("{} {}", Names[i], rng.gen_range(1000..9999)).as_str();
}
}
13 | fn connectPesel(Names: &mut Vec<&str>){
| - let's call the lifetime of this reference `'1`
...
16 | Names[i] = format!("{} {}", Names[i], rng.gen_range(1000..9999)).as_str();
| -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------- temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| assignment requires that borrow lasts for `'1`
|
Try changing the type of Names to &mut Vec<String>, since the caller needs to be responsible for freeing the memory once it is done using the string, rather than freeing it immediately. (See https://dev.to/stevepryde/rust-string-vs-str-1l93)

Static lifetime for a temporary variable? [duplicate]

This question already has answers here:
How to convert a String into a &'static str
(4 answers)
How can you make a safe static singleton in Rust?
(3 answers)
How do I create a global, mutable singleton?
(7 answers)
Closed 3 years ago.
I have the following function:
fn load_data() -> Result<MyData> {
// ...
Ok(my_data)
}
I want to call this function only once during the execution of my program and save the result in a static variable.
It'd be nice if the result is of type Option<MyData>, so the consumer just needs to check if the data is there or not, regardless of the reason of why it's not there.
I have came up with the following:
lazy_static! {
static ref DATA: Option<&'static MyData> = load_data().ok().as_ref();
}
However, that line fails:
35 | static ref DATA: Option<&'static MyData> = load_data().ok().as_ref();
| ----------------^^^^^^^^^
| | returns a value referencing data owned by the current function
| |
| |
| temporary value created here
Is there a way to achieve what I want or am I conceptually wrong?

Temporary value is freed at the end of this statement [duplicate]

This question already has answers here:
"borrowed value does not live long enough" when using the builder pattern
(1 answer)
"borrowed value does not live long enough" seems to blame the wrong thing
(2 answers)
Why is it legal to borrow a temporary?
(3 answers)
Why does the compiler tell me to consider using a `let` binding" when I already am?
(2 answers)
Closed 4 years ago.
I'm trying to scrape a webpage using the Select crate:
let document = Document::from_read(response).unwrap();
for node in document.find(Class("lia-list-row")) {
let title = node.find(Class("page-link")).next().unwrap();
let title_text = title.text().trim();
println!("{}\n", title_text);
}
Which results in following error:
let title_text = title.text().trim();
^^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
creates a temporary which is freed while still in use
println!("{} - {}\n", i, title_text);
---------- borrow used here, in later iteration of loop
I solved it by separating the .text() and .trim()
let title_text = title.text();
let trim_text = title_text.trim();
What is the difference? Why did the first attempt fail?
This one seems convoluted at first, but remember that String and &str are different beasts.
String can live and be used on its own, but &str is just a reference to part of String. So, &str can live as long as referenced String lives. Lets see how it should work on return signatures.
let title_text = title .text() .trim();
// ^ ^ ^
// Node String <- &str
Here, title is a select::Node.
Node::text returns a String, but nothing binds it to context.
String::trim, in turn, returns a &str which is a reference to part of String itself.
In the end, the borrow checker just doesn't understand how it should process a reference to String that will not live long enough in context, as it is a temporary value (non-bound).

Cannot print a process::Command because "borrowed value does not live long enough" [duplicate]

This question already has answers here:
"borrowed value does not live long enough" when using the builder pattern
(1 answer)
Builder pattern - borrowed value does not live long enough
(1 answer)
Closed 4 years ago.
I want a way to print the command with its arguments. In my real case, those arguments are generated and I want to see the command that we're going to run.
I'm trying to do this:
fn main() {
use std::process::Command;
let x = Command::new("sh").arg("2");
let y = x.output();
println!("status: {:#?}", x);
println!("status: {:#?}", y);
}
error[E0597]: borrowed value does not live long enough
--> src/main.rs:4:13
|
4 | let x = Command::new("sh").arg("2");
| ^^^^^^^^^^^^^^^^^^ - temporary value dropped here while still borrowed
| |
| temporary value does not live long enough
...
10 | }
| - temporary value needs to live until here
|
= note: consider using a `let` binding to increase its lifetime
I can get it to work if I don't add the .arg("2") above, but that doesn't help me with my usecase.
All the other examples on stackoverflow doesn't seem to help me solving this.
Command::arg takes self by mutable reference, so you need to store the Command returned by Command::new in a variable before calling arg, otherwise the Command would be dropped at the end of the statement. (The compiler could in theory use a hidden variable here as it does in other circumstances, but it doesn't do it as of Rust 1.29.)
fn main() {
use std::process::Command;
let mut x = Command::new("sh");
x.arg("2");
let y = x.output();
println!("status: {:#?}", x);
println!("status: {:#?}", y);
}

Are there any ways to mitigate or workaround mutably capturing the environment in a closure used in a loop? [duplicate]

This question already has answers here:
Can't borrow mutably within two different closures in the same scope
(1 answer)
Problems with mutability in a closure
(1 answer)
Closed 4 years ago.
The check_vec() closure captures a mutable reference to the values vector. The compiler is not smart enough to understand that values.push(0xbeef) call is safe. I have tried compiling using NLL feature flag, but that didn't help either.
fn main() {
let mut values = Vec::with_capacity(16);
let mut check_vec = || {
if values.len() < 16 {
values.push(0xdead);
}
};
for _ in 0..32 {
check_vec();
values.push(0xbeef);
}
check_vec();
}
(playground)
error[E0499]: cannot borrow `values` as mutable more than once at a time
--> src/main.rs:12:9
|
4 | let mut check_vec = || {
| -- first mutable borrow occurs here
5 | if values.len() < 16 {
| ------ previous borrow occurs due to use of `values` in closure
...
12 | values.push(0xbeef);
| ^^^^^^ second mutable borrow occurs here
...
16 | }
| - first borrow ends here
Are there any ways to mitigate or workaround this limitation?

Resources