this post was submitted on 22 Oct 2023
4 points (83.3% liked)
Rust
5999 readers
4 users here now
Welcome to the Rust community! This is a place to discuss about the Rust programming language.
Wormhole
Credits
- The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)
founded 1 year ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
The key thing to understand is that in Rust, references are considered unique types. This means that
&T
is a separate type fromT
.So, for #1, it is not saying that
T
implementsCopy
, it is saying that regardless of whatT
is,&T
implementsCopy
. This is because, by definition, it is always valid to copy a shared reference, even ifT
itself is notCopy
.Part of the reason this is confusing is that traits often include references in their function signatures; and in particular,
Clone::clone
has the signaturefn clone(&self) -> Self
. So whenT
implementsclone
, it has a method that takes&T
and returnsT
. But even though the signature takes&T
, the type that implementsClone
isT
itself. (&T
always implementsClone
as well, just as it always implementsCopy
, but as withCopy
, this is independent from whetherT
itself implementsClone
. See for example the error message you get when explicitly cloning a shared reference: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a1b80cc83570321868c4ad55ee3353dc)Since
Copy
is a marker trait, it doesn't have any associated methods making it explicit thatCopy
affects how&T
can be used. However,Copy
requires the type to implementClone
(even though you can implementClone
in terms ofCopy
) and implies thatT
can always be automatically created from&T
without an explicit call toT::clone
, so you can think of the "signature" forCopy
as matching that ofClone
, even though there's no actualcopy
method.For #2, I recommend thinking in terms of explicit types. Adding annotations, you get:
The type of
x
isBox
. You cannot assign ani32
to aBox
; they're different types! But the type of*x
isi32
, and thus you can assign84
to it.The trait used to make
Box
behave this way isDerefMut
, which explicitly makes*x
assignable: https://doc.rust-lang.org/std/ops/trait.DerefMut.html