'How to return a Vec containing variables created in a function
I want to return a Vec from a method that contains the two variables created in the method.
I know the problem is that the variable created in the method will be destroyed when the method ends。What should I do if I want to return this Vec?
fn thing2vec(thing: &Thing) -> Vec<&str> {
let offset = chrono::FixedOffset::east(8 * 3600);
let bt = chrono::NaiveDateTime::from_timestamp(thing.begin_ts as i64, 0).add(offset);
let et = match thing.end_ts {
0 => {
"-"
}
_ => {
chrono::NaiveDateTime::from_timestamp(thing.end_ts as i64, 0).add(offset).to_string().as_str()
}
};
vec!(&thing.id, &thing.name, &format!("{}", thing.status), &bt.to_string(), et, &thing.comment)
}
error message:
|
21 | chrono::NaiveDateTime::from_timestamp(thing.end_ts as i64, 0).add(offset).to_string().as_str()
| ------------------------------------------------------------------------------------- temporary value created here
...
25 | vec!(&thing.id, &thing.name, &format!("{}", thing.status), &bt.to_string(), et, &thing.comment)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
|
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
Solution 1:[1]
If you really need to keep it a Vec, the simplest answer to pick an owned type, ie. Vec<String>, and clone if you need to. Like other comments said Cow could work as well, but does add its own complications.
If it were me, this looks like a structured format so I would just turn it into a struct and return it that way:
struct NewThing<'a> {
id: &'a str,
name: &'a str,
status: String,
// ..etc.
}
Solution 2:[2]
If not converting the &strs to Strings is important for performance, you can use Cow:
fn thing2vec<'a>(thing: &'a Thing) -> Vec<Cow<'a, str>> {
let offset = chrono::FixedOffset::east(8 * 3600);
let bt = chrono::NaiveDateTime::from_timestamp(thing.begin_ts as i64, 0).add(offset);
let et = match thing.end_ts {
0 => Cow::Borrowed("-"),
_ => Cow::Owned(
chrono::NaiveDateTime::from_timestamp(thing.end_ts as i64, 0)
.add(offset)
.to_string(),
),
};
vec![
Cow::Borrowed(&thing.id),
Cow::Borrowed(&thing.name),
Cow::Owned(format!("{}", thing.status)),
Cow::Owned(bt.to_string()),
et,
Cow::Borrowed(&thing.comment),
]
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | wannabe |
| Solution 2 |
