3 ms·
I think Rust does this quite well. There are a few handy rules. 1. If the first argument of a function is `self`, then that function is treated as a method and
by bobbylarrybobby 4y ago
I think Rust does this quite well. There are a few handy rules.
1. If the first argument of a function is `self`, then that function is treated as a method and can be called like `obj.meth(args)`. Functions without `self` must be called statically, which in the case of an object would look like `Type::meth(obj, args)`. The second form is used occasionally by common wrapper types like Box and Rc to avoid dereferencing “piercing the veil” and calling a method on the wrapped object (Rust has no separate `obj->meth` syntax, which IMO is its own issue).
2. Having access to `Self` lets you specify the types of non-this arguments as well as return types, like `fn add(self, other: Self) -> Self {...}`. You can also use it as the name of the type when (de)structing objects, e.g., `let Self { fields } = other` or `return Self { fields }`. Writing out the name of the current type each time could get unwieldy.
3. `Self` as a namespace is handy when dealing with enums, e.g., `match self { Self::First => ..., Self::Second => ...}` or static functions like `Self::func(args)`. It's crucial in trait implementations when referring to associated types, e.g., in Iterator there's `type Item; fn next(&mut self) -> Option<Self::Item>;`
I don't why a Self variable would be placed on the stack differently from non-Self variables; method calls have always just been syntactic sugar + namespacing for a free function, no?
- quietbritishjim 4y ago> method calls have always just been syntactic sugar + namespacing for a free function, no? Not quite; they're more than that for languages that have dynamic dispatch, like virtual methods in C++ or dyn impl in Rust. In that case, that argument affects which function is called. In the case of multiple inheritence (in C++), the implicit this parameter is also potentially subject to a pointer offset; if it's virtual multiple inheritence then that offset may even be computed at runtime.