2

The following program tries to store a Thing in a Holder:

struct Holder:
    var thing: Thing
    fn __init__(inout self, owned thing: Thing):
        self.thing = thing
        pass

struct Thing:
    fn __init__(inout self):

thing = Thing()
Holder(thing^)

When I run the program, I get the following error message:

error: Expression [59]:8:22: value of type 'Thing' cannot be copied into its destination
        self.thing = thing

Here's why I expected this code to run without errors:

  • The ^ transfers ownership, so the module scope no longer owns thing
  • __init__ takes Thing as owned

I know I can make the code run by implementing a __copyinit__ but is there a way to avoid the copy?

When I translate to Rust the program compiles and runs:

struct Holder {
    thing: Thing
}

struct Thing {}


fn main() {
    Holder { thing: Thing {} };
}

rust playground

1 Answer 1

0

You need to implement the Thing.__moveinit__ function and also pass the ownership between varibales inside the __init__ function: from thing argument variable to self.thing member variable

struct Thing:
    fn __init__(inout self):
        ...

    fn __moveinit__(inout self, owned other: Self):
        ...

struct Holder:
    var thing: Thing
    fn __init__(inout self, owned thing_arg: Thing):
        self.thing = thing_arg^ # <--- see the transfer operator (^) here

fn main():
    let thing = Thing()
    let holder = Holder(thing^)

It's a bit confusing but there are 3 variables instead of 2, if you name all of them thing it's easy to miss it:

  • varible thing
  • argument thing_arg
  • field self.thing
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.