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 <di...@ubuntu.com
<mailto:di...@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@mozilla.org <mailto:Rust-dev@mozilla.org>
    https://mail.mozilla.org/__listinfo/rust-dev
    <https://mail.mozilla.org/listinfo/rust-dev>


_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to