3 ms·
Basics: When you're writing (or read someone else's) functions, you should be considering three types of parameters: * (&) borrowed * (mut &) mutably
by steamer25 10y ago
Basics:
When you're writing (or read someone else's) functions, you should be considering three types of parameters:
* (&) borrowed
* (mut &) mutably borrowed
* () moved
The borrow operator should be your default/go-to decoration. Don't use the more destructive exchanges until the compiler forces you to. As I write this out, I'm thinking this might be a small short-coming in Rust's design. I.e., read/borrowed should maybe be the default/undecorated behavior and special pains should be required to move a reference.
Anyway, borrowed means, "I just wanna read some stuff off of that. I promise not to change a thing!"
Mutable borrowing means, "Gimme that--I'm going to change it! Expect it to differ as part of the output of this function."
Moving means, "That's mine now! I'm going to wreck it beyond any usage you'd try to do after I'm done. If you think you still want it, better hand me a clone."
It might also be good to spend some time working through the book if you haven't already: https://doc.rust-lang.org/stable/book/ https://doc.rust-lang.org/stable/book/
Here're some HN comments about advanced patterns:
* https://news.ycombinator.com/item?id=13470592#13470904
* https://news.ycombinator.com/item?id=13470975
* Also recommends http://cglab.ca/~abeinges/blah/too-many-lists/book/
- steamer25 10y agoAlso, save and recompile early and often. If you're using IntelliJ IDEA [Community Edition] with the Rust plugin, compiling is just ctrl + r .
- speg 10y agoIs the borrow syntax (&x) a reference while vanilla (x) is by value? Or are both passed by reference but with different ownership affects? Reason I'm asking is I got hung up the other day on passing a String to a function that accepted &str which someone explained to me Strings dereference to &str but I think I just ended up more confused.
- steamer25 10y ago> Is the borrow syntax (&x) a reference while vanilla (x) is by value? Or are both passed by reference but with different ownership affects? This is briefly addressed in the FAQs: "What is the difference between passing by value, consuming, moving, and transferring ownership? These are different terms for the same thing. In all cases, it means the value has been moved to another owner, and moved out of the possession of the original owner, who can no longer use it. If a type implements the Copy trait, the original owner’s value won’t be invalidated, and can still be used." https://www.rust-lang.org/en-US/faq.html#what-is-the-difference-between-consuming-and-moving https://www.rust-lang.org/en-US/faq.html#what-is-the-differe... There are more details in the chapter on the stack and the heap from the book (https://doc.rust-lang.org/book/the-stack-and-the-heap.html https://doc.rust-lang.org/book/the-stack-and-the-heap.html)... "The stack is very fast, and is where memory is allocated in Rust by default." "What do other languages do? Most languages with a garbage collector heap-allocate by default. This means that every value is boxed. There are a number of reasons why this is done, but they’re out of scope for this tutorial. There are some possible optimizations that don’t make it true 100% of the time, too. Rather than relying on the stack and Drop to clean up memory, the garbage collector deals with the heap instead." So unless your data structure is boxed, it's allocated on the stack and passed by value and different ownership effects apply as well. > I got hung up the other day on passing a String to a function that accepted &str which someone explained to me Strings dereference to &str but I think I just ended up more confused. String literals de-sugar to &str. E.g., fn borrow_str(s: &str) {} borrow_str("foo"); // This works borrow_str(String::new()) // this doesn't work fn take_str(s: String) {} take_str("foo") // Doesn't work take_str(String::new()) // works take_str("foo".to_owned()) // works
- 10y ago