[rust-dev] Mutable files

David Henningsson diwic at ubuntu.com
Sun Jul 20 20:12:37 PDT 2014



On 2014-07-21 04:43, Steven Fackler wrote:
> Some types are implicitly copyable. They implement the built-in trait
> Copy. A type is Copy if it is
>
> a) numeric primitive (e.g. f32 or uint), or
> b) an immutable reference (e.g. &Foo or &str), or
> c) a raw pointer (e.g. *const Foo or *mut Foo), or
> d) a collection of Copy types (e.g. struct Foo { a: int, b: &'static str }).
>
> In addition, if a type implements Drop, it is no longer Copy.
>
> Steven Fackler

Cool, thanks for the answer. These restrictions seem somewhat complex.

This wasn't very intuitive for me, so just throwing this out (feel free 
to ignore if it has already been discussed :-) )

 From a language design perspective, maybe it would be more intuitive to 
have different syntaxes for copy and move, like:

let mut g = f; /* Copies from f to g, error if f is a non-Copy type */

let mut g <- f; /* Moves from f to g, error if trying to use f afterwards */

Or in the File/BufferedReader example, this would be something like:

let f = File::open(filename);
let mut reader = BufferedReader::new(<- f); /* Bye bye f! */

I'm also afraid that if a library struct decides to change between a 
copy and non-copy type, this would cause subtle errors in users of that 
library that expected the other type. But if the compiler is guaranteed 
to catch all such errors even with today's handling, maybe that is not 
too much to worry about.


>
>
> On Sun, Jul 20, 2014 at 7:39 PM, David Henningsson <diwic at ubuntu.com
> <mailto:diwic at ubuntu.com>> wrote:
>
>
>
>     On 2014-07-21 03:33, Patrick Walton wrote:
>
>         On 7/20/14 6:29 PM, David Henningsson wrote:
>
>             Hi,
>
>             Consider these two examples:
>
>             1)
>
>             let mut file = File::open(filename);
>             file.read(buf);
>
>             2)
>
>             let file = File::open(filename);
>             let mut reader = BufferedReader::new(file);
>             reader.read(buf);
>
>             My question is: in example 2, why doesn't BufferedReader
>             need "file" to
>             be mutable? After all, BufferedReader ends up calling
>             file.read(), which
>             needs a mutable reference to the file.
>
>             It looks like I'm able to "bypass" the mutability
>             requirement, just
>             because I wrap the file inside a BufferedReader?
>
>
>         Because `BufferedReader::new` moves `file` and takes ownership
>         of it.
>         (You can see this if you try to use `file` again: the compiler will
>         prevent you.) Mutability is inherited through ownership in Rust:
>         that
>         is, the current owner determines the mutability of a piece of
>         data. So,
>         the mutability of `reader` determines the mutability of the `File`
>         object at the time you try to read, and the mutability
>         restriction is
>         satisfied.
>
>
>     Thanks for the quick answer!
>
>     I did two more examples to try to understand when things are moved:
>
>     3)
>     struct Dummy {
>        foo: int,
>        bar: int
>     }
>
>     let f = Dummy {foo: 10, bar: 5};
>     let mut g = f; // Here the assignment copies..?
>     println!("{}", f.foo + g.foo); // Ok
>
>     4)
>
>     let f = File::open(filename);
>     let mut g = f; // Here the assignment moves..?
>     f.tell(); // Fails - use of moved value
>
>     How come that the assignment moves in example 4), and copies in
>     example 3)?
>
>     // David
>
>     _________________________________________________
>     Rust-dev mailing list
>     Rust-dev at mozilla.org <mailto:Rust-dev at mozilla.org>
>     https://mail.mozilla.org/__listinfo/rust-dev
>     <https://mail.mozilla.org/listinfo/rust-dev>
>
>


More information about the Rust-dev mailing list