Hello, I am a rust newbie here. This has probably been answered multiple times but I am struggling to understand most of the answers on the internet and "The Rust Programming Book". I am currently working with polars and am getting an error along the lines of this
|
96 | let dataframe = CoolStruct::helper().with_columns(
| --------- binding `dataframe` declared here
...
100 | let groups = dataframe.groupby(["symbol"]).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `dataframe` is borrowed for `'static`
...
108 | }
| - `dataframe` dropped here while still borrowed
So what's happening here is that I have a helper function that returns a dataframe. Instead of returning the dataframe itself though, it appears that rust is returning a reference to the dataframe or letting our main function "borrow" the dataframe. The issue is that when the function ends, the borrowed value gets wiped off of the memory. What exactly is the correct way to "transfer" the ownership of the object. The solution it proposes is to give the borrow a lifetime of 'static, but I am not sure exactly how to do that. Also, about lifetimes, why do certain objects require lifetimes and others don't? My struct CoolStruct looks like this
pub(crate) struct CoolStruct<'a> {
columns: Vec<String>,
symbols: Vec<String>,
frame: DataFrame,
symbol_groups: GroupBy<'a>
}
Why does GroupBy specifically need a lifetime specifier while the other objects do not? If it was heap-allocated memory wouldn't it be easier to let the programmer deallocate the memory when appropriate? If I use the 'static lifetime, am I leaking memory by keeping the object in memory until the program finishes executing?
Here is a small sample of the code that caused the error above:
pub(crate) struct CoolStruct<'a> {
columns: Vec<String>,
symbols: Vec<String>,
frame: DataFrame,
symbol_groups: GroupBy<'a>
}
impl CoolStruct<'_> {
fn helper(symbols: &Vec<String>) -> DataFrame {
let mut df = DataFrame::default();
for symbol in symbols {
let json_tree = serde_json::to_string("{some json}").unwrap();
let cursor = Cursor::new(json_tree);
let mut tmp_df = JsonReader::new(cursor).finish().unwrap().clone().lazy().with_columns(
[
polars::prelude::lit(ticker.as_str()).alias("symbol")
]
).collect().unwrap();
tmp_df.set_column_names(vec!["symbol", "a", "b", "c"].as_slice()).expect("Collumn number mismatch");
df = df.vstack(&tmp_df).unwrap();
}
return df;
}
pub(crate) fn new(mut symbols: Option<Vec<String>>) -> CoolStruct<'static> {
if symbols.is_none() {
symbols = Some(vec!["aaa"].iter().map(|s| String::from(*s)).collect());
}
assert!(symbols.is_some());
let columns_list: Vec<String> = vec!["symbol", "a", "b", "c"].iter().map(|s| String::from(*s)).collect();
let symbols_list = symbols.unwrap();
let dataframe = CoolStruct::helper(&symbols_list);
let groups = dataframe.groupby(["symbol"]).unwrap();
CoolStruct {
columns: columns_list,
symbols: symbols_list,
symbol_groups: groups,
frame: dataframe
}
}
}