For example, a moved-out-from tree in C++ could represent this by having its inner root pointer be nullptr, and then its dtor would have to check for the root being nullptr, and all its member fns would have the danger of UB (nullptr dereference) if the caller called them on a moved-out shell. But the Rust version could use a non-nullable pointer type (Box), and its dtor and member fns would be guaranteed to act on a valid pointer.
Note that assuming the into_iter comes from IntoIterator that’s what the for loop invokes to get an iterator from an iterable. So
for lr in LoadRequests.into_iter() {
Is completely unnecessary verbosity, for lr in LoadRequests {
Will do the exact same thing. And the stdlib will generally implement the trait with the relevant semantics on shared and unique references so for lr in LoadRequests.iter_mut()
Can generally be written for lr in &mut LoadRequests
So you rarely need to invoke these methods outside of functional pipelines if you dislike them (some prefer them for clarity / readability).the difference between `const Data& d` and `const Data d` isn't accurately characterized as "a typo" -- it's a semantically significant difference in intent, core to the language, critical to behavior and outcome
even if the author "forgot" to add the `&` due to a typo, that mistake should absolutely have been caught by linting, tests, CI, or code review, well before it entered the code base
so not feelin' it, sorry
I've been writing some Swift code in recent years. The most frequent source of bugs has been making incorrect assumptions on whether a parameter is a class or a struct (reference or value type). C# has the same issue.
It's just a terrible idea to make the value/reference distinction at the type level.
All good linters complain about const buffer data missing the ampersand btw
It extends it a bit, too, with `out` meaning that the referenced argument is initialized by the function, not read.
struct Data {
// Vec cannot implement "Copy" type
data: Vec<i32>,
}
// Equivalent to "passing by const-ref" in C++
fn BusinessLogic(d :&Data) {
d.DoThing();
}
// Equivalent to "move" in C++
fn FactoryFunction(d: Data) -> Owner {
owner = Owner{data: d};
// ...
return owner
}
Is this really true?I believe in Rust, when you move a non-Copy type, like in this case, it is up to the compiler if it passes a reference or makes a physical copy.
In my (admittedly limited) understanding of Rust semantics calling
FactoryFunction(d: Data)
could physically copy d despite it being non-Copy. Is this correct?EDIT:
Thinking about it, the example is probably watertight because d is essentially a Vec (as Ygg2 pointed out).
My point is that if you see
FactoryFunction(d: Data)
and all you know is that d is non-Copy you should not assume it is not physically copied on function call. At least that is my believe.Another problem with C++ references is that they aren't really reference types, they are aliases, so they have wonky semantics and crazy nonsensical features like `const T&` doing lifetime extension
If you care about performance, you measure it. If you don't measure performance, you don't care about it.
This reminds me of arguing more than once with JS developers about the dangers of loose typing (especially in the case of JS) and getting the inevitable reply ”I just keep track of my type casting.”.
Regarding const by-value parameters, they should never appear in function declarations (without definition) since that doesn’t enforce anything. In function definitions, you can use const refs (which have lifetime extension) to achieve the same const-correctness, and const refs are better for large types.
Admittedly this further proves the point that c++ is needlessly complicated for users, and I agree with that.
Exactly, this is not an issue in any reasonable setup because static analysis catches (and fixes!) this reliably.
> but evidently these issues go unnoticed until a customer complains about it or someone actually bothers to profile the code.
No
Rust: Typo? Now it just doesn't compile anymore. Worst case is that the compiler does a bad job at explaining the error and you don't find it immediately.
C++: Typo? Good luck. Things may now be broken in so subtle and hard to figure out ways it may haunt you till the rest of your days.
But that of course depends on the nature of the typo. Now I should go and read the article.