Cow
Borrow module
Ref video timestmap | Rust Doc
Cow
-
A
Cow
is a Clone on write smart pointer -
Its and enum which is either
Borrowed
orOwned
-
So
Cow<T>
either contains aBorror<T>
or ownsT
-
a
Cow
implementsDeref
. 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:- if it owns the value, it simply does the modification
- 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)] 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 onStrings
returns aCow<str>
. It returns aBorrowed
if the string is valid utf-8. Otherwise, it converts it into aVec
and replaces all invalid chars and returns thatOwned
value. This is a great example whereCow
lets you not to modify when not needed.