I'm new to Rust and want to start a new desktop project using Rust (floating point calculation-intensive), where I intend to make use of the multi-threading Rust capabilities to split tasks in parallel in a 8-core processor. I need to read/write simple text files. I've noticed that the io system in Rust has undergone major changes recently (with the approximation of the launching of version 1.0.0) -- I read some threads in the forums and I got a bit confused...
I tried to create/write-into a text file using a simplification of an example from std::fs::File. I ran it with the beta1.0.0 and with the current nightly on Windows-7 64 bits. Get an error. Below are the code (4 lines ) and the error. Tried to remedy the thing in a couple other ways (e.g. using old_io, googling some examples) but always got into errors.
I would appreciate very much both a pointer to my mistake and a pointer to up-to-date docs about the io and fs systems that will be stable in Rust 1.0.0.
Thanks in advance and regards
Jose
//////// CODE //////
//use std::io::prelude::*;
use std::fs::File;
fn main() {
let mut f = File::create("foo.txt");
f.write_all("Hello, world!");
}
//////////////// ERROR ////////////////
rustc t2.rs
t2.rs:7:4: 7:30 error: type core::result::Result<std::fs::File, std::io::error::Error> does not implement any method in scope named write_all
t2.rs:7 f.write_all("Hello, world!");
^~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Exit code: 101
Have a look at the std::fs::File API. If you scroll down to the create() function, you'll notice that create() returns a Result<File>, and not a File. What you'll want to do is wrap your create() method call with the try!() macro. That macro automatically unwraps the Result if everything went OK, otherwise it will return the error that was called. See below:
use std::fs::File;
fn main() {
let mut f = try!(File::create("foo.txt"));
f.write_all("Hello, world!");
}
That won't actually work because you can't return anything from main. You should either handle the error:
use std::io::Write;
use std::fs::File;
let mut f = match File::create("foo.txt") {
Err(e) => {
println!("Couldn't open foo.txt");
return;
},
Ok(f) => f,
};
f.write_all(b"Hello world!");
Or assert that there is no error and panic if there is:
use std::io::Write;
use std::fs::File;
let mut f = File::create("foo.txt").unwrap(); // Panics (see the docs) if create failed.
f.write_all(b"Hello, world!");
Unfortunately I still get errors when compiling (with Rust 1.0.0 beta) your code snippet. BTW, the error is the same in Rustc 1.0.0-beta on Linux Mint 17.1 over a VirtualBox.
Thx for your help
Jose
/////////////////////////////
:5:8: 6:42 error: mismatched types:
expected (),
found core::result::Result<_, _>
(expected (),
found enum core::result::Result) [E0308]
:5 return $ crate:: result:: Result:: Err (
:6 $ crate:: convert:: From:: from ( err ) ) } } )
:1:1: 6:48 note: in expansion of try!
t2.rs:14:13: 14:43 note: expansion site
t2.rs:15:3: 15:29 error: type std::fs::File does not implement any method in scope named write_all
t2.rs:15 f.write_all("Hello, world!");
^~~~~~~~~~~~~~~~~~~~~~~~~~
t2.rs:15:29: 15:29 help: methods from traits can only be called if the trait is in scope; the following trait is implemented but not in scope, perhaps add a use for it:
t2.rs:15:29: 15:29 help: candidate #1: use std::io::Write
error: aborting due to 2 previous errors
Unfortunately I still get errors when compiling your code (with Rust 1.0.0 beta). The write_all method still is not recognized? Output below.
Thx for your help
Jose
////////////
t2.rs:23:3: 23:28 error: type std::fs::File does not implement any method in scope named write_all
t2.rs:23 f.write_all("Hello world!");
^~~~~~~~~~~~~~~~~~~~~~~~~
t2.rs:23:28: 23:28 help: methods from traits can only be called if the trait is in scope; the following trait is implemented but not in scope, perhaps add a use for it:
t2.rs:23:28: 23:28 help: candidate #1: use std::io::Write
error: aborting due to previous error
Thank you very much arielb1, that does the trick. I thought "write_all" was accessible with "use std::fs::File" because in the example in std::fs::File ( -- the link you suggest --) there is no "use std::io::Write" writte. Perhaps the docs are not fully updated?
Thanks again
Jose
update: Oops, the line " use std::io::prelude::*; " in the examples which I commented out also does the trick...
Well I will be damned. I think it might be a good idea to use the std library in the docs, because it might not be immedeately obvious what that means, i know i glossed over it.
i know i glossed over it, so probably doesn't mean much
But it came out completely wrong!
I like to think that extension traits and how they interact is one of the worst (and if not my least favorite) gotchas in Rust. I think documenting the need for the use std::io::prelude::* is sufficient, other than just it being in the docs. just my 2cents, keep up the good work!