| ▲ | rauli_ a day ago | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
For someone who has decades of experience from other programming languages this does not look clear to me at all but rather confusing. Calling an method can change value of variable of primitive type? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | ninkendo a day ago | parent | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There’s nothing special about primitives, they’re just types like any other. A method taking `&mut self` can always modify self, on any type. But you can only call such methods if the value is mutable to begin with, so it’s not really that interesting. It’s only weird if you come from languages like Java where “primitives” are distinct from “objects”, which is a self-imposed limitation the language imposes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | rtpg a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
C++ lets you do this kind of stuff as well. Primitive types and composite types having the same capabilities is a bit of a value statement for C++ and Rust IMO, and it's missing in a lot of languages downstream (IMO) of the "every variable is a reference to a slot/pointer" philosophy taken by most every managed language | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | stusmall a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The big clue that'll jump out to any rust dev is the type signature: pub const fn toggle(&mut self) The "&mut" says that toggle takes a mutable reference to the instance it is called off of. This is also called a mutable borrow. You might think that would get buried in the program because you don't always check the type signature of every method you call, but there are a few reasons that muts really jump out in rust. The languages immutable by default nature is one and the other is that several IDE have features to specifically draw attention to mutable instances/references. It's a fairly common pattern in rust to have helper methods on a type that take a mutable reference or ownership of self. TL;DR: Rust's ownership model is very unique. Once it clicks its the cat's pajamas, but experience in other languages don't map well to this part of the language. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | zdimension a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
When you call a method on something in Rust, the method gets passed that something (as a parameter called self). But the method gets to choose whether it's by move/copy or by reference. Here, toggle gets the bool passed by mutable reference. In effect, if x is a bool, doing x.toggle() is rewritten by the compiler as bool::toggle(&mut x), which can of course modify x. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | saghm a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Not quite; the method uses `&mut self`, so it actually operates on a mutable reference to the value that happens to be a primitive. If you declare a boolean without specifying the binding as mutable, you'd get a compiler error from trying to call this method. Moreover, if anything else had a reference to it at the same time, it would also cause a compiler error to call this method. This is definitely something that Rust does a bit different than most other languages, but it's not anything specific to this method, booleans, or particularly new to the language. Most people will learn about the common different ways of defining a method (via ownership, shared reference, or mutable reference) fairly early on in programming Rust. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | scott_w a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Why wouldn’t it be possible? The distinction in modern languages between primitive and not is an arbitrary one when it comes to stuff like this. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | torginus 16 hours ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I think a major issue in all OOP languages is determining which operation mutates and which does not, and often having both operations, or even worse, if there's a third, static method. This is redundant and creates opportunity for code style divergence. An example would be having both `Vector3.Add` and `Vector3.AddToSelf` instance methods as well as third `Vector3::Add` which takes two Vector3s. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | crabmusket a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I guess you're experiencing the feeling a mathematician gets when seeing a line like x = x + 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | jason_oster a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Think of having the method for AtomicBool, where you are forced to call methods for all value accesses. `atomic_bool.toggle(Ordering::SeqCst)` would read much better than `atomic_bool.fetch_xor(true, Ordering::SeqCst)`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | nicoburns a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
What may be surprising to you coming from other languages, is that primitive types in Rust have their own methods! So methods applying to primitives is not unusual at all in Rust. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | 15 hours ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [deleted] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | throwaway2037 a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
What languages? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | worik a day ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> Calling an method can change value of variable of primitive type? So long as the variable is mutable it's value can be changed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ▲ | kibwen a day ago | parent | prev [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
In addition to what the sibling commenters have written, in order for this to compile, the variable would need to be declared as mutable. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||