3 ms·
Yep! fn foo(self: Self) void {} fn bar(self: *const Self) void {} fn baz(self: *Self) void {} In this example, `foo` and `bar` cannot modify `self`,
by kristoff_it 4y ago
Yep!
fn foo(self: Self) void {}
fn bar(self: *const Self) void {}
fn baz(self: *Self) void {}
In this example, `foo` and `bar` cannot modify `self`, while `baz` can. In the case of `foo`, `self` is passed in by value, but since function arguments are immutable in Zig, it cannot be modified (the compiler might still opt for pass-by-reference under the hood, but the semantics don't change).
In the case of `bar` we are explicitly asking for a constant pointer, as you mentioned.
- MatthiasPortzel 4y agoI spent a lot of this weekend learning Zig, and this was the most surprising this for me. foo, bar, and baz are all called the same way (as thing.foo() or thing.baz()), but depending on the type signature, the compiler can figure out whether you want a mutable or immutable reference to the object.
- masklinn 4y agoIt’s pretty common for languages in the field e.g. C++ (const versus non-const methods), Rust (value, unique reference, shared reference, deref), and even Go (value v pointer, delegation). The “method syntax” is pretty much just a convenience, so why not also handle that after all?
- WalterBright 4y agoThis is common behavior for languages. D adds another wrinkle to it - a reference can be mutable, const, or immutable. mutable: can modify it const: cannot modify it through the reference, but other mutable references can still modify it immutable: nobody can modify it The 'immutable' is great for writing threaded code, as no synchronization is necessary.