What for is the impl block?

In view of the last answer to the: Cannot find function - #14 by piter76
I began to wonder, what is the point of the impl block? All I can do in impl block I can do with free standing functions? What am I missing?

You might want to check out the Implementations chapter from the Rust Reference for a formal definition of what an impl block is used for.

Here are some benefits of inherent impl blocks compared to free functions.

  • impl is the only way to define functions that can be called using "method call" syntax foo.bar().
  • Functions implemented on a type are grouped together in documentation, making them easier to discover and browse.
  • When you import a type, you automatically get access to its associated functions. For example, if you write use std::collections::HashSet; then you can write let mut x = HashSet::new(); x.insert(0); without needing to import the new and insert functions separately.

These are generally things that are nice to have, but not fundamentally necessary, so using an inherent impl instead of free functions is more a choice of style than functionality. (The same thing is often true in other languages like C++, when deciding between a class method versus a free function.)

(Trait implementations are a separate matter, which has a more fundamental impact on how a type can be used.)

Here's a silly example of using impl scoped functions vs. free functions:

struct Test1(u8);
impl Test1 {
    fn new(value: u8) -> Self {
        Self(value)
    }
    fn value(&self) -> u8 {
        self.0
    }
}

struct Test2(u8);
fn new_test2(value: u8) -> Test2 {
    Test2(value)
}
fn test2_value(this: &Test2) -> u8 {
    this.0
}

fn main() {
    let t1 = Test1::new(5);
    dbg!(t1.value());
    
    let t2 = new_test2(7);
    dbg!(test2_value(&t2));
}

You're noticing something correct, though: there's nothing particularly special about functions in an impl block. It's a way to organize your code, just like putting code in different modules. Functions with acceptors fn(&self, obj: Obj) allow the subject-verb-object syntax (subject.verb(object)), which is just syntactic sugar for SubjectType::verb(&subject, object).

Implementing traits are a different thing though.

1 Like

My point exactly.

That third point is what's sells it to me really.
Thanks

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.