rust - Is there any way to return a reference to a variable created in a function? -
i want write program write file in 2 steps. file may not exist before program run. filename fixed.
the problem openoptions.new().write()
can fail. in case, want call custom function trycreate()
. idea create file instead of opening , return handle. since filename fixed, trycreate()
has no arguments , cannot set lifetime of returned value.
how can resolve problem?
use std::io::write; use std::fs::openoptions; use std::path::path; fn trycreate() -> &openoptions { let f = openoptions::new().write(true).open("foo.txt"); let mut f = match f { ok(file) => file, err(_) => panic!("err"), }; f } fn main() { { let f = openoptions::new().write(true).open(b"foo.txt"); let mut f = match f { ok(file) => file, err(_) => trycreate("foo.txt"), }; let buf = b"test1\n"; let _ret = f.write(buf).unwrap(); } println!("50%"); { let f = openoptions::new().append(true).open("foo.txt"); let mut f = match f { ok(file) => file, err(_) => panic!("append"), }; let buf = b"test2\n"; let _ret = f.write(buf).unwrap(); } println!("ok"); }
fjh absolutely correct, want comment bit more , touch on of other errors code.
is there way return reference function without arguments?
technically "yes", want, "no".
a reference points existing piece of memory. in function no arguments, things referenced global constants (which have lifetime &'static
) , local variables. i'll ignore globals now.
in language c or c++, take reference local variable , return it. however, function returns, there's no guarantee memory referencing continues thought was. might stay expect while, memory reused else. code looks @ memory , tries interpret username amount of money left in bank account, problems arise!
this rust's lifetimes prevent - aren't allowed use reference beyond how long referred-to value valid @ current memory location.
instead of trying return reference, return owned object. string
instead of &str
, vec<t>
instead of &[t]
, t
instead of &t
, etc.
your actual problem
look @ documentation openoptions::open
:
fn open<p: asref<path>>(&self, path: p) -> result<file>
it returns result<file>
, don't know how you'd expect return openoptions
or reference one. function work if rewrote as:
fn trycreate() -> file { openoptions::new().write(true).open("foo.txt").expect("couldn't open") }
this uses result::expect
panic useful error message. of course, panicking in guts of program isn't super useful, it's recommended propagate errors out:
fn trycreate() -> io::result<file> { openoptions::new().write(true).open("foo.txt") }
and option
, result
have lots of nice methods deal chained error logic. here, can use or_else
:
let f = openoptions::new().write(true).open("foo.txt"); let mut f = f.or_else(|_| trycreate()).expect("failed @ creating");
i'd create "inner main" returns result
. together, including fjh's suggestions:
use std::io::{self, write}; use std::fs::openoptions; fn inner_main() -> io::result<()> { let mut f = openoptions::new() .create(true) .write(true) .append(true) .open("foo.txt")?; f.write(b"test1\n")?; f.write(b"test2\n")?; ok(()) } fn main() { inner_main().expect("an error occurred"); println!("ok"); }
Comments
Post a Comment