Use &str, &T, and &[T] for Function Parameters

Sources:
https://rust-unofficial.github.io/patterns/idioms/coercion-arguments.html?highlight=string#use-borrowed-types-for-arguments
https://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html

When borrowing String, Box, and Vec in a function, use &str, &T, and &[T] instead of &String, &Box, and &Vec. There are two advantages.

  • String, Box, and Vec are basically pointers already, so adding & will have another layer of indirection.
  • &str, &T, and &[T] provide more flexibility. They accept not only &str, &T, and &[T] but also &String, &Box, and &Vec.

One of the sources above illustrates this well.

fn print_me(msg: &str) { println!("msg = {}", msg); }

fn main() {
    let string = "hello world";
    print_me(string);

    let owned_string = String::from("hello world"); // or String::from_str("hello world")
    print_me(&owned_string);

    let boxed_string = std::boxed::Box::new(String::from("hello world"));
    print_me(&boxed_string);

    let counted_string = std::rc::Rc::new(String::from("hello world"));
    print_me(&counted_string);

    let atomically_counted_string = std::sync::Arc::new(String::from("hello world"));
    print_me(&atomically_counted_string);
}