Cow

Borrow module

Ref video timestmap | Rust Doc

Cow

Rust Doc

  • A Cow is a Clone on write smart pointer

  • Its and enum which is either Borrowed or Owned

  • So Cow<T> either contains a Borror<T> or owns T

  • a Cow implements Deref. So if it holds a reference, it just passes-through the access. If it owns the value, the reference is returned

  • If we try to modify the value in a Cow and:

    1. if it owns the value, it simply does the modification
    2. if its a borrowed value/shared reference, it can't directly modify it so it clones the value and turns it into the Owned version and gives us a mutable reference
  • Useful in cases where we only sometimes need to modify a value. eg: a string escaping function

    
    #![allow(unused_variables)]
    fn main() {
    // Without using cow, the function would look something like this:
    // fn escape<'a>(s: &'a str) -> String
    // but for a string that does not need to be escaped, allocating a String
    // is wasteful. A Cow allows us to Clone only when its necessary
    // so the function becomes something like:
    fn escape<'a>(s: &'a str) -> Cow<'a, str> {
        if already_escaped(s) {
            Cow::Borrowed(s)
        } else {
            let mut string = s.to_string();
            // modify (escape) string here
            Cow::Owned(string)
        }
    }
    }
    
  • a real world example is where the from_utf8_lossy function on Strings returns a Cow<str>. It returns a Borrowed if the string is valid utf-8. Otherwise, it converts it into a Vec and replaces all invalid chars and returns that Owned value. This is a great example where Cow lets you not to modify when not needed.