Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Let's work through the example

1. There's a user-defined type named Thing with a String inside it.

2. We've got a function named findThing, which takes an array of Things and a string name, performs a linear search of the array and returns a mutable reference to the Thing with that name or if it's not found it doesn't. In Go, this function accidentally gives back a mutable reference to a copy of the Thing.

3. We make an array of things, use findThing to find one of them and try to mutate it.

We can translate 1 into Rust easily, it's just struct Thing { Name: String } and the compiler will moan because this is deeply unconventional naming in Rust and that warns by default.

We can translate 3 into Rust easily too, the compiler moans about our naming again.

But when we try to translate 2 by writing findThing we struggle. Rust wants to understand what lifetime to associate with this mutable reference we're returning. If we try to make a copy, where does the copy live? Rust doesn't have garbage collection, so if it just goes out of scope the lifetime ends and Rust will reject this function as nonsense - you can't return references which have expired, silly programmer, try again.

If we don't make a copy we can successfuly tie the lifetime to the array, but then we don't have the Go bug, so the thing you say "could happen in Rust" doesn't happen.

Here's a Godbolt link for a working example: https://rust.godbolt.org/z/shKj6rEz7

Now, try to adjust it to have the same bug, I expect it will be much harder to do this wrong.



Ah, I was working on a mistaken assumption about the Go example code (I thought the function returned Thing, whereas actually it returns *Thing). That will teach me to RTFA...


Right, I think Julia would spot that if we get a Thing back, it's clearly not the Thing inside our array, because those are necessarily different Things.

If the function does return Thing, in Rust we can implement the mistake, returning a copy, but there's no plausible way to implement the intended functionality, we can get the matching thing out of an array we're allowed to mutate -- by swapping it, but now some different Thing is in the array of Things instead, that's what swapping means. If we're given the actual array, not a (mutable) reference as a parameter, we can destroy it and keep just the matching Thing to return, but now our caller hasn't got a Things array, it was destructively moved to give us a parameter.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: