We've been told that we should always write
Rc::clone(&r) and not
In the book we read:
Rc::clonefor reference counting, we can visually distinguish between the deep-copy kinds of clones and the kinds of clones that increase the reference count. When looking for performance problems in the code, we only need to consider the deep-copy clones and can disregard calls to
On the other hand, the document of the
Clone trait says:
[Clone] differs from Copy in that Copy is implicit and an inexpensive bit-wise copy, while Clone is always explicit and may or may not be expensive...
...but you may reimplement
Cloneand run arbitrary code.
And to some extent it clarifies that
clone is not necessarily a deep copy. However, currently in the book in several places
clone is used like a deep copy:
As we know, when we deep copy object
a and create object
b, that means we'll get two independent objects
b. There should be no way that manipulating
a's state affects
b's state and vice versa.
Rc, as long as the data to which it is pointing is immutable, we'll get an independent copy. However, if we make that data mutable, the clone created by
Rc::clone will not be an independent copy. If a program assumes that an object which implements the
Clone trait makes independent copies with its
clone function, an Rc which contains a
RefCell can become problematic. (like this example or this example)
Is it really necessary and is it a good idea to recommend calling
clone like an associated function for shared smart pointers? (i.e. like
Rc::clone(&r) and not
r.clone()) This is not just about
Rc. Any struct that contains a shared smart pointer will be subject to this recommendation. In my opinion this is just adding unnecessary complexity to the rust development. Now a programmer can be a "bad rust developer" just because he's used
r.clone() in his code. This type of recommendations are always troublesome.
For this reason, I suggest that one of these solutions be chosen:
- We can introduce a new trait for deep copy and then deprecate all current implementations of the
Clonetrait that are doing a deep copy. (the new trait will replace them)
- We can introduce a trait for costume copy semantics or even without introducing a new trait, we deprecate all implementations of the
Clonetrait that are performing some type of costume/shallow copy. For example
Rc::cloneshould be deprecated and get replaced with a function like
This will reduce the probability of misunderstandings.