Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New ownership guide #17138

Closed

Conversation

steveklabnik
Copy link
Member

This is the start of the new "Ownership" guide, to replace the lifetimes guide.

I'm still working on it, but I wanted to share my progress, as this guide is very important, and I'd like as many eyes on it as possible. 😄

@steveklabnik
Copy link
Member Author

I also only deprecated the old one 😉 ❤️ @huonw

@Manishearth
Copy link
Member

Yay! I'll read through the whole thing when I get time. Couple of things:

  • Could this guide also explain the difference between moved and copied types?
  • It should probably discuss clone() too, and any other common errors and how to escape them

These two are related. Changing `struct SomeStruct` to `struct
SomeStruct<'struct>` adds a **lifetime parameter**. This parameter gives a
name to the lifetime of a reference to this struct. In this case, we've given
it the name 'struct,' since that's what it's the lieftime of. You can use any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo, lifetime

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sigh

@steveklabnik
Copy link
Member Author

@Manishearth move semantics aren't exactly the same thing as ownership. clone() is something that will end up being discussed, of course.

@Manishearth
Copy link
Member

Hm, agreed, but I found them closely related. While learning Rust at first I didn't realize the difference between move/copy values and thus confused myself a lot. It took me a while to consolidate &/&mut, ~ (now box), clone, ref, and move/copy semantics and understand the memory model properly enough to use it without fighting the compiler. While they're theoretically something different, practically they turn up in similar places. But I guess discussing it elsewhere is okay, as long as they are discussed :)

structure itself, but the structure _also_ contains a pointer to a `str`. We
have no guarantee that the reference inside of `a_string` is valid for the
entire time that the reference to the `SomeStruct` itself. If it's not, then we
could have a valid reference to a `SomeStrut` which contained an invalid

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SomeStrut -> SomeStruct?

@huonw
Copy link
Member

huonw commented Sep 11, 2014

move semantics aren't exactly the same thing as ownership

Ownership implies move semantics, and values moving are one of the major ways people hit ownership... they're intimately linked.

(e.g. taking a x: &T to y: T via y = *x requires taking the data out of x by value and placing it into y, which requires transferring ownership, cf. my answer here.)

}
```

The `box` keyword allocates memory on the heap, and places a `Box<int>` there.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds like what lives in the heap is a Box<int>. But that's not true. In your case x living on the stack would be a Box<int>, a handle you can use to reach the heap-allocated int.

}

fn main() {
let x = box SomeStruct { a_string: "A string" };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This x is a pointer.

@mitchmindtree
Copy link
Contributor

If you could also include an example and short explanation of situations in which references to traits require lifetime bounds that'd be awesomely helpful! I still don't quite have a clear grasp on why they're required as a bound when you already provide a lifetime with the reference?

@ftxqxd
Copy link
Contributor

ftxqxd commented Sep 19, 2014

I feel like calling this just an ‘Ownership Guide’ is a bit confusing. Sure, ownership can be a source of many problems for newcomers, but I suspect that another big reason people will come here is to learn about lifetimes after getting a confusing error about them. Calling it just an ‘Ownership Guide’ would make it much harder to find. Perhaps this could be the ‘Ownership and Lifetimes Guide’, if only for the sake of discoverability?

I suppose that if this is linked to from the tutorial it wouldn’t be too bad, but chances are at least some people will skip that link until they bump into a lifetime-/ownership-related error.

@charlieflowers
Copy link

You sneak a "box" in there when you get the code compiling. You explicitly point out your addition of the lifetime parameter, but you sneak the "box" in without discussing it. Would it not compile without box? It appears like it would, but I haven't tried it. I just know as a learner, if I didn't know what box meant, I'd no longer feel like I was able to follow your discussion.

@huonw
Copy link
Member

huonw commented Sep 20, 2014

I think both code examples originally had box, and it was removed from the first and accidentally not removed from the second, this also explains the inconsistencies @sellibitze and @mahkoh pointed out above.

Of course, it would be very limiting to only have a single possible pointer to
a resource. If you need additional pointers, Rust offers a second concept:
borrowing. Another reference may borrow the contents of a pointer which has
ownership. Here's an example:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know Rust, but this bit seems confusing. You seem to imply that x in the example below is a pointer and it doesn't look like it in the code below.

I'm not sure how to rephrase it best if that's not the case...

@steveklabnik
Copy link
Member Author

There's enough random problems with this, and it's already out of date, so I'm just going to give it a close and make a new draft instead.

@steveklabnik steveklabnik deleted the new_ownership_guide branch October 25, 2017 18:26
lnicola pushed a commit to lnicola/rust that referenced this pull request May 19, 2024
…-new, r=Veykril

feature: Make generate function assist generate a function as a constructor if the generated function has the name "new" and is an asscociated function.

close rust-lang#17050
This PR makes `generate function assist` generate a function as a constructor if the generated function has the name "new" and is an asscociated function.
If the asscociate type is a record struct, it generates the constructor like this.
```rust
impl Foo {
    fn new() -> Self {
        Self { field_1: todo!(), field_2: todo!() }
    }
}
```
If the asscociate type is a tuple struct, it generates the constructor like this.
```rust
impl Foo {
    fn new() -> Self {
        Self(todo!(), todo!())
    }
}
```
If the asscociate type is a unit struct, it generates the constructor like this.
```rust
impl Foo {
    fn new() -> Self {
        Self
    }
}
```
If the asscociate type is another adt, it generates the constructor like this.
```rust
impl Foo {
    fn new() -> Self {
        todo!()
    }
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.