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.
-
implis the only way to define functions that can be called using "method call" syntaxfoo.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 writelet mut x = HashSet::new(); x.insert(0);without needing to import thenewandinsertfunctions 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.
My point exactly.
That third point is what's sells it to me really.
Thanks