3 ms·
Well, that's another nice thing with Rust. Maybe it's not the saviour language but at least it brings clarity to ownership of values.
by kzrdude 2y ago
Well, that's another nice thing with Rust. Maybe it's not the saviour language but at least it brings clarity to ownership of values.
- foldr 2y agoI think the same thing could happen in Rust. foo.x = bar will compile if foo is a copy or if it's a mutable reference. As in Go, you'd have to explicitly type 'foo' in order for any compiler error to show up.
- tialaramex 2y agoLet'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 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.
- deleted 2y ago[deleted]
- foldr 2y agoAh, 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...
- tialaramex 2y agoRight, 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.