Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a way to have a function for a implementation for a struct that moves self instead of borrowing it as &self or &mut self?

I have been dealing with this because I want to create a style of configuration that is somewhat of functional as it would be used like:

struct.set_config(myConfig)
      .set_other_config(myOtherConfig)

And to do this I need to return a owned version of the struct or another type that is similar to it in my case.

And to do this I would actually need to borrow that into a implemented function of that struct. My thought would be that it would look something like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

impl MyStruct {
  fn set_config(self, ...) -> Self {
    (...do something with self)

    self // return the mutated self
  }
}

But when trying something similar to this the Rust compiler did not like that very much.

Is there any way to kind of implement this? Or at least another way to get what I want without this?

EDIT:

My problem with just adding "mut self" is the Rust compiler seemed to complain with a warning:

warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
    = note: `#[deny(patterns_in_fns_without_body)]` on by default

And I wanted to avoid that. This error originates in the trait that defines that function not in the implementation.

EDIT 2:

I am working on a Machine Learning crate and I have layers for a Model, there is a Layer trait and I want to have Initializers for instantiating the parameters depending on how the user wants to initialize them.

Another important thing is that I have a enum that can be all of the layers currently implemented in the crate, this enum has that same trait implemented and each method has a match for each possible type of Layer.

Currently in the crate, to define the layers for a model you currently need to do something like:

let layers = vec![
  Dense::new(...),
  TanH::new(...)
];

(The "new" method returns that enum that has all the implemented layers as variants)

I want to set the initializers (which are now a field of these layers’s structs) as such:

let layers = vec![
  Dense::new(...).set_initializer(...),
  TanH::new(...)
];

Then the set_initializer would need to return that enum owning the Dense layer for example. Hence my problem.

The important part of my Layer trait definition would need to look like this:

pub trait Layer<'a> {
    (...)

    fn set_initializer(mut self, initializer: Initializer) -> ModelLayer<'a>; // This is the enum I mentioned

    (...)
}

>Solution :

The pattern_in_fns_without_body error triggers on mut self parameters in body-less function signatures. This includes functions without bodies in trait definitions.

All you need to do to resolve the error is change mut self to just self in your trait definition:

pub trait Layer<'a> {
    // ...

    fn set_initializer(self, initializer: Initializer) -> ModelLayer<'a>;

    // ...
}

I’m not sure what version of Rust you’re working with, but recent versions of the compiler have a hint recommending just that:

error: patterns aren't allowed in functions without bodies
 --> src/lib.rs:7:24
  |
7 |     fn set_initializer(mut self, initializer: Initializer) -> ModelLayer<'a>;
  |                        ^^^^^^^^ help: remove `mut` from the parameter: `self`
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
  = note: `#[deny(patterns_in_fns_without_body)]` on by default
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading