function - How do you return non-copyable types? -
i trying understand how return non-primitives (i.e. types not implement copy
). if return i32
, function creates new value in memory copy of return value, can used outside scope of function. if return type doesn't implement copy
, not this, , ownership errors.
i have tried using box
create values on heap caller can take ownership of return value, doesn't seem work either.
perhaps approaching in wrong manner using same coding style use in c# or other languages, functions return values, rather passing in object reference parameter , mutating it, can indicate ownership in rust.
the following code examples fails compilation. believe issue within iterator closure, have included entire function in case not seeing something.
pub fn get_files(path: &path) -> vec<&path> { let contents = fs::walk_dir(path); match contents { ok(c) => c.filter_map(|i| { match { ok(d) => { let val = d.path(); let p = val.as_path(); some(p) }, err(_) => none } }) .collect(), err(e) => panic!("an error occurred getting files {:?}: {}", pa th, e) } }
the compiler gives following error (i have removed line numbers , extraneous text):
error: `val` not live long enough let p = val.as_path(); ^~~ in expansion of closure expansion expansion site reference must valid anonymous lifetime #1 defined on block... ...but borrowed value valid block suffix following statement let val = d.path(); let p = val.as_path(); some(p) },
you return value by... returning it. however, signature shows trying return reference value. can't when object dropped @ end of block because reference become invalid.
in case, i'd write like
#![feature(fs_walk)] use std::fs; use std::path::{path, pathbuf}; fn get_files(path: &path) -> vec<pathbuf> { let contents = fs::walk_dir(path).unwrap(); contents.filter_map(|i| { i.ok().map(|p| p.path()) }).collect() } fn main() { f in get_files(path::new("/etc")) { println!("{:?}", f); } }
the main thing function returns vec<pathbuf>
— collection of type owns path, , more references else's memory.
in code, let p = val.as_path()
. here, val
pathbuf
. call as_path
, defined as: fn as_path(&self) -> &path
. means given reference pathbuf
, can reference path
that live long pathbuf
will. however, trying keep reference around longer vec
exist, dropped @ end of iteration.
Comments
Post a Comment