3

Here's what I'm trying to do: open all the command line arguments as (binary) files and read bytes from them. The constantly changing syntax here is not conductive to googling, but here's what I've figured out so far:

use std::io::{File, result};
use std::path::Path;
use std::os;

fn main() {
    let args = os::args();
    let mut iter = args.iter().skip(1); // skip the program name

    for file_name in iter {
        println(*file_name);
        let path = &Path::new(*file_name);
        let file = File::open(path);
    }
}

Here's the issue:

test.rs:44:31: 44:41 error: cannot move out of dereference of & pointer
test.rs:44         let path = &Path::new(*file_name);

I've hit a brick wall here because while I'm fine with pointers in C, my understanding of the different pointer types in rust is practically non-existent. What can I do here?

rene
  • 41,474
  • 78
  • 114
  • 152
John Ledbetter
  • 13,557
  • 1
  • 61
  • 80
  • 1
    We just added a pointer tutorial, it might help your general understanding of pointers: http://static.rust-lang.org/doc/0.9/guide-pointers.html – Steve Klabnik Jan 13 '14 at 03:44

1 Answers1

4

Try &Path::new(file_name.as_slice())

Unfortunately, due to the trait argument that Path::new() takes, if you pass it a ~str or ~[u8] it will try and consume that type directly. And that's what you're passing with *file_name. Except you can't move out of a pointer dereference in Rust, which is why you're getting the error.

By using file_name.as_slice() instead (which is equivalent, in this case, to (*file_name).as_slice(), but Rust will do the dereference for you) it will convert the ~str to a &str, which can then be passed to Path::new() without a problem.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • Could you please explain some more what's going on inside of `as_slice()`. From the source code [(linked)](http://static.rust-lang.org/doc/master/src/std/home/rustbuild/src/rust-buildbot/slave/doc/build/src/libstd/str.rs.html#1280-1282), it looks like a lifetime is getting attached? What does it mean "can't move out of a pointer dereference"? – Kipton Barros Jan 11 '14 at 20:53
  • @KiptonBarros: `.as_slice()` returns a borrowed reference to the data. It does have a lifetime, which matches the lifetime of the value it was called on. As for "can't move out of a pointer dereference", any affine type, which owned values (e.g. `~str`) are, can't be implicitly copied. If something attempts to move them, that marks the original location of the value as moved and, therefore, unusable. For example, `let a = ~"foo"; let b = a; println!("{}", a)` tells you that `a` is moved. However, you cannot move out of a pointer, because the compiler can't tell what it pointed to. – Lily Ballard Jan 12 '14 at 00:19
  • @KiptonBarros: To continue that previous code example, if you try to say `let a = ~"foo"; let b = *&a;` you get the error "cannot move out of dereference of & pointer". The problem is the compiler cannot mark `a` as having been moved, since it can't know that `b` held a reference to `a` (well, in this trivial example it can, but in any non-trivial example it can't). And it's unsafe to use a moved value, so the compiler has to disallow the move as the only other option is to break safety. – Lily Ballard Jan 12 '14 at 00:20