Add a `shallow_clone` method to Cow (reopen #33777)

I suggest to reopen collections: Add `shallow_copy` method to Cow which always reborrows data - Pull Request #33777

I find even the restricted version very useful. Here is my use case:

use std::borrow::Cow;

pub trait CloneExt<'b> {
    /// Clone a `Cow` without memory allocation.
    /// Note, the original must outlive the clone! Use case:
    /// ```
    /// use tpnote_lib::clone_ext::CloneExt;
    /// use std::borrow::Cow;
    /// fn do_something_or_nothing(v: Cow<str>) -> Cow<str> {
    ///     if v.len() > 3 {
    ///         let s = "Hello ".to_string() + &*v;
    ///         Cow::Owned(s)
    ///     } else {
    ///         v
    ///     }
    /// }
    /// // Sometimes, we only have a `&Cow`, but we need a `Cow`!
    /// let a: &Cow<str> = &Cow::Owned("world!".to_string());
    /// let b: Cow<str>  = a.shallow_clone();
    /// assert_eq!(do_something_or_nothing(b), "Hello world!");
    ///
    /// let a: &Cow<str> = &Cow::Owned("ld!".to_string());
    /// let b: Cow<str>  = a.shallow_clone();
    /// assert_eq!(do_something_or_nothing(b), "ld!");
    /// ```
    fn shallow_clone(&'b self) -> Cow<'b, str>;
}

impl<'b> CloneExt<'b> for Cow<'b, str> {
    fn shallow_clone(&'b self) -> Cow<'b, str> {
        match *self {
            Self::Borrowed(b) => Self::Borrowed(b),
            Self::Owned(ref o) => Self::Borrowed(o.as_ref()),
        }
    }
}

Why can't you just do Cow::Borrowed(&**self)?

2 Likes

It confuses me to call this a "clone" when all it does is borrow. To me, "shallow clone" implies that it's copying the top-level content of a Cow::Owned and not changing any pointers to heap allocations in that content, not copying the heap allocations to which those pointers point, unlike the usual "deep" clone. (This often would be unsound, of course.)

My bikeshed color suggestion for a name is as_borrowed or as_borrow.

2 Likes

The is no purpose of using Cow as a return type when Borrowed is the only possible variant. In a more general form, the thing you are looking for is called cow.borrow().

3 Likes

Add shallow_clone() method to Cow which always reborrows data · Issue #283 · rust-lang/libs-team

since this does not create an independent value

This is also true for clone() in case of borrowed content.

The reason why I suggest ...clone() in the name, is because of the use case: I have a &Cow, but I need a Cow, what do I do? I look out for something like clone().

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.