this post was submitted on 15 Nov 2024
8 points (100.0% liked)

Rust Programming

8161 readers
24 users here now

founded 5 years ago
MODERATORS
 

Let's say I have a struct Event which implements the method permalink:

struct Event {
    base_url: String,
    rel_permalink: String,
    permalink: String,
    title: String,
}

impl Event {
    fn permalink(&self) -> String {
        let permalink = format!("{}{}", self.base_url, self.rel_permalink);
        permalink
    }
}

The method takes 2 fields of the struct and the target would be to return the definition of another field.

Later I instantiate an event1: Event:

let event1 = Event {
                base_url: base_url,
                rel_permalink: rel_permalink.to_string(),
                title: node.value().name().to_string(),
                permalink = permalink(),
            };

Essentially I would like the field permalink to be the value returned by the method permalink, is something like this possible, is this correct? I couldn't find something similar in the docs..

Pheraps using an associated function as constructor would be a better way to handle a similar situation?

Thank you so much!

top 6 comments
sorted by: hot top controversial new old
[–] RustyNova 6 points 6 hours ago* (last edited 5 hours ago) (1 children)

It's quite simple. Just remove the permalink field! If you are calculating it then no need to store it in the struct.

If you do need the field to be there (ex you serialise it with serde), then create a method called new that takes everything but the permalink, construct your permalink there, then return a new object.

Your permalink method can now just be self.permalink.to_string()

P.S. in the second case I'd recommend to change the return type of self.permalink() to &str. It avoids unnecessary cloning of the string.

[–] [email protected] 2 points 4 hours ago (1 children)

It’s quite simple. Just remove the permalink field! If you are calculating it then no need to store it in the struct.

This is inefficient. It should be the other way around. Remove base_url and rel_permalink, and store permalink and the rel_permalink offset.

That way, you can get a zero cost &str for any of the three.

[–] RustyNova 2 points 1 hour ago

Technically yes, but a newbie doesn't need that. I doubt it's an application that performance is so critical either.

Too much premature optimisation IMO

[–] [email protected] 2 points 6 hours ago* (last edited 6 hours ago) (1 children)

Hmm, yeah, I'd use a constructor method:

impl Event {
    pub fn new(base_url: String, rel_permalink: String, title: String) -> Self {
        let permalink = format!("{}{}", self.base_url, self.rel_permalink);

        Self {
                base_url,
                rel_permalink,
                title,
                permalink,
         };
    }

    // ...
}

Then you'd instantiate it like so:

let title = node.value().name().to_string();
let event = Event::new(base_url, rel_permalink.to_string(), title);
[–] [email protected] 1 points 6 hours ago* (last edited 6 hours ago) (1 children)

~~Is it really valid to call permalink() in that context, since it requires &self? There's no self in that context afaik. Can't test it now but it looks suspicious~~

EDIT: Invalid since the comment was updated

[–] [email protected] 2 points 6 hours ago

Sorry, I posted the comment, then realized that problem. 😅