[rust-dev] Newbie questions about memory management

Colin Fleming colin.mailinglist at gmail.com
Sun Dec 30 12:50:49 PST 2012


Great, thanks for the clarifications, Niko, that helps a lot. I think I'll
probably use the borrowed pointer notation.

I'm assuming that the compiler optimisation you describe works for any
function returning an rvalue, not just for something that looks like a
constructor (i.e. functions called "new" are not special in any way)?

Thanks,
Colin


On 31 December 2012 03:48, Niko Matsakis <niko at alum.mit.edu> wrote:

> You have two options.
>
> If you wish to use a borrowed pointer, you may write the function `new()`
> like so:
>
> static fn new(value: &lifetime/str) -> StringReader/&lifetime {
>   StringReader { data: value, next: 0 }
> }
>
> The notation StringReader/&lifetime is (probably) not well-documented.
> What it means is: "a StringReader instance which contains borrowed
> pointers with the lifetime `lifetime`".  So basically it is specifying the
> lifetime of the `value` field, in this case.  Note that if the
> `StringReader` had multiple borrowed pointers contained within, they would
> all have to have the same lifetime.
>
> Alternatively, you could have the StringReader own the data it is reading
> from, in which case you would want to use an `@str` or `~str`, just as you
> showed.  Ultimately, we would probably want both types in the standard
> library, since each can be useful in different circumstances.
>
> Regarding your second question, the compiler makes some effort to
> construct data precisely into the location where it is needed.  So in the
> constructor function above, what happens is that a pointer into the
> caller's stack is passed as an implicit first parameter.  The struct is
> then written directly into the caller's stack.  This works so long as the
> return expression itself constructs the struct (more generally, so long as
> you return an rvalue).  It would not work if you stored the struct into a
> variable and returned that.
>
> e.g., although there is no semantic difference, this program would *not*
> be optimized:
>
> static fn new(value: &lifetime/str) -> StringReader/&lifetime {
>   let r = StringReader { data: value, next: 0 };
>   return r;
> }
>
> Here the compiler would produce a memcpy.
>
>
> Niko
>
>
>
> Colin Fleming wrote:
>
> Hi all,
>
> I'm playing around with Rust a little having been interested in it for a
> while. I've read the language and borrowed pointers tutorials but I'm still
> struggling with what seems like a fairly trivial example.
>
> I have a StringReader type:
>
> struct StringReader {
>   data: &str,
>   mut next: uint
> }
>
> and I'm trying to create a constructor for it:
>
> impl StringReader {
>   static fn new(value: &str) -> StringReader {
>   StringReader { data: value, next: 0 }
>   }
> }
>
> I can't do this because the compiler "cannot infer an appropriate
> lifetime", which I take to mean that it can't work out the lifetime of
> 'value', probably because I shouldn't be using a borrowed pointer here.
>
> I tried a named lifetime, to indicate that the returned StringReader
> pointer should be valid as long as the string is:
>
> static fn new(value: &lifetime/str) -> &lifetime/StringReader {
>   &StringReader { data: value, next: 0 }
> }
>
> but that doesn't work either since the lifetime of the return value is not
> the same as the lifetime of the param.
>
> I also tried by value:
>
> struct StringReader {
>   data: str,
>   mut next: uint
> }
>
> static fn new(value: str) -> StringReader {
>   StringReader { data: value, next: 0 }
> }
>
> but to my amazement "bare `str` is not a type" - I'd expected this just to
> create an inefficient copying version.
>
> The only thing I've managed to get to work is an owned string:
>
> struct StringReader {
>   data: ~str,
>   mut next: uint
> }
>
> static fn new(value: ~str) -> StringReader {
>   StringReader { data: value, next: 0 }
> }
>
> Is this my best option here? What is the best practice for constructors?
>
> Another thing that I don't quite understand: according to the tutorials, a
> struct constructed so:
>
> StringReader { data: value, next: 0 }
>
> is allocated on the stack. How does this work with the return value of the
> constructor? Since the return value is only in scope in the constructor
> body, I suppose this means that the return value of the constructor is
> copied - isn't this inefficient for constructors?
>
> Thanks for any and all clarification,
> Colin
>
> _______________________________________________
> Rust-dev mailing listRust-dev at mozilla.orghttps://mail.mozilla.org/listinfo/rust-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121231/ef7f0378/attachment.html>


More information about the Rust-dev mailing list