std: clarify Clone trait documentation about duplication semantics

This commit improves the Clone trait documentation to address confusion
around what "duplication" means for different types, especially for smart
pointers like Arc<Mutex<T>>.

Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
This commit is contained in:
xizheyin
2025-05-18 16:38:43 +08:00
parent a69bc17fb8
commit cea87ecad6

View File

@@ -38,7 +38,16 @@
mod uninit; mod uninit;
/// A common trait for the ability to explicitly duplicate an object. /// A common trait that allows explicit creation of a duplicate value.
///
/// Calling [`clone`] always produces a new value.
/// However, for types that are references to other data (such as smart pointers or references),
/// the new value may still point to the same underlying data, rather than duplicating it.
/// See [`Clone::clone`] for more details.
///
/// This distinction is especially important when using `#[derive(Clone)]` on structs containing
/// smart pointers like `Arc<Mutex<T>>` - the cloned struct will share mutable state with the
/// original.
/// ///
/// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while /// 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. In order to enforce /// `Clone` is always explicit and may or may not be expensive. In order to enforce
@@ -147,7 +156,16 @@ mod uninit;
#[rustc_diagnostic_item = "Clone"] #[rustc_diagnostic_item = "Clone"]
#[rustc_trivial_field_reads] #[rustc_trivial_field_reads]
pub trait Clone: Sized { pub trait Clone: Sized {
/// Returns a copy of the value. /// Returns a duplicate of the value.
///
/// Note that what "duplicate" means varies by type:
/// - For most types, this creates a deep, independent copy
/// - For reference types like `&T`, this creates another reference to the same value
/// - For smart pointers like [`Arc`] or [`Rc`], this increments the reference count
/// but still points to the same underlying data
///
/// [`Arc`]: ../../std/sync/struct.Arc.html
/// [`Rc`]: ../../std/rc/struct.Rc.html
/// ///
/// # Examples /// # Examples
/// ///
@@ -157,6 +175,23 @@ pub trait Clone: Sized {
/// ///
/// assert_eq!("Hello", hello.clone()); /// assert_eq!("Hello", hello.clone());
/// ``` /// ```
///
/// Example with a reference-counted type:
///
/// ```
/// use std::sync::{Arc, Mutex};
///
/// let data = Arc::new(Mutex::new(vec![1, 2, 3]));
/// let data_clone = data.clone(); // Creates another Arc pointing to the same Mutex
///
/// {
/// let mut lock = data.lock().unwrap();
/// lock.push(4);
/// }
///
/// // Changes are visible through the clone because they share the same underlying data
/// assert_eq!(*data_clone.lock().unwrap(), vec![1, 2, 3, 4]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "cloning is often expensive and is not expected to have side effects"] #[must_use = "cloning is often expensive and is not expected to have side effects"]
// Clone::clone is special because the compiler generates MIR to implement it for some types. // Clone::clone is special because the compiler generates MIR to implement it for some types.