You’ve heard a lot about it, you’ve bought into the hype, and the day has finally come. It’s time for you to start writing Rust!
So you sit down, hands on the keyboard, heart giddy with anticipation, and write a few lines of code. You run the cargo run command, excited to see whether the program works as expected. You’ve heard that Rust is one of those languages that simply works once it’s compiled. The compiler starts up, you follow the output, then, suddenly:
error[E0382]: borrow of moved value
Uh-oh. Looks like you’ve run into the dreaded borrow checker! Dun, dun, DUUUUUUN!
I want to start the series with multiple mutable references. We’ve just learned about ownership, and it doesn’t look that hard. We follow some simple rules, we even managed to write some code, see some ownership errors, and fix them.
This beginner Rust tutorial, unlike most others, features ownership front-and-center. Short examples highlight the practical consequences of ownership. I'm no Rust expert. However, I have tried to choose examples that speak for themselves, and descriptions that jibe with reputable sources when possible.
In this article we'll take a closer look at Rust's Ownership model and how it manages memory.
This blog post will take a deep dive into the Rust world of mutability. By deep dive, it means the blog post is considerably long. So it will take time to go through the different examples. The topic we will dive through is specific but we will have to go through various Rust concepts: Ownership/Borrowing, Lifetimes, Unsafe, Sync, Closures, Macros and more. This might be intimidating and I think this is where many developers are put off.
Implications of Rust's borrow checking and memory ownership on GUI development (simple case)
One of the biggest Rust’s pros is unique ownership system. Unfortunately, it is also one of the hardest thing to learn. In this article I will try to explain it the same way I had learnt it and how I introduce people to one.
I wanted to write an article about one aspect of Rust I really put off for a long while — lifetimes. They are one of the hardest parts about Rust to wrap one’s brain around. Many of us are simply not used to a compiler with a paradigm around memory ownership where such things are needed.
Lifetimes help the compiler make your code safer (i.e. less prone to crashing by using unexpected places in memory). Even if we don’t write them in our code, the compiler is smart enough to figure out your lifetimes without you under the covers. They are often times your secret allies, so let's learn a bit about them.
Following the previous post, here I am going to introduce the key concepts of Rust — Ownership and Borrowing.
Rust has a perception of being a very difficult language to learn. I had a similar experience, but just as I was told, there is a point where things start to get a lot easier. This post aims to describe the hard parts that I had to get through in order to start being productive with Rust in the belief that this may help others get over the hill to that sweet spot of infinite bliss and productivity. In this post, I’m going to cover references and borrowing.
Today we’re looking at the rust borrow checker from a different perspective. As you may know, the borrow checker is designed to safely handle memory allocation and ownership, preventing accessess to invalid memory and ensuring data-race freedom. This is a form of resource management: the borrow checker is tracking who’s in charge of a chunk of memory, and who is currently allowed to read or write to it. In this post, we’ll see how these facilities can be used to enforce higher-level API constraints in your libraries and software. Once you’re familiar with these techniques, we’ll cover how the same principles apply to advanced memory management and handling of other more abstract resources.
I’ve been writing on a few examples code lately to add to documentations of some crates of mine. I write a lot of code that creates new objects that need other objects in order to be built. Most of the APIs you can see around tend to love the borrow principle – and I do.
It’s not immediately obvious that calling min(squares) modifies squares. If squares were a list or even a range, we would be able to call min and max on it with no problem. It would be nice if the language prevented us from trying to use something twice that can only be used once. Almost all modern languages, both statically and dynamically typed, will fail at runtime in these situations.
It’s still not problem.
It’s not my problem.
I spent pretty much the whole day banging my head against the wall trying to figure out how ownership and borrowing work in Rust, and finally have a grasp on what’s going on.
In this post I’m going to demonstrate how these concepts work through some examples of code that break Rust’s rules, and explain why they’re problematic. I assume very little knowledge of the Rust programming language. I’ve also added comments to all of the code blocks that indicate whether the code is valid Rust or not.
The networking working group is pushing hard on async/await notation for Rust, and @withoutboats in particular wrote a fantastic blog series working through the design space. I wanted to talk a little bit about some of the implications of async/await, which may not have been entirely clear. In particular, async/await is not just about avoiding combinators; it completely changes the game for borrowing.
Ownership and borrowing are the fundamentals of data structures in Rust. However, both taking owneship of a value (moving it) or taking a reference to it can only happen after the value was created. This ordering seems to prevent having any cycle in a data structure, even though that’s sometimes useful or necessary. For example in a web page’s content tree, from any DOM node, one can easily access (if any) its first and last child, previous and next sibling, (so children of a node form a doubly-linked list) and parent. Some other applications might need to manipulate arbitrary graphs in their full generality.
View all tags