Sunday, July 11, 2021

Accepting both Vec or slice of String or &str in Rust

In whathever programming language, it’s rather common to have a function which accepts an array of strings. Specifically in Rust, there is the notion of slice, which can be used as a reference to a Vec. And also there is the notion of &str, which can be used as a reference to String. Putting both concepts together as an argument is not trivial, though.

Turns out I found a way to make it work by using the AsRef trait – as many things in Rust, traits lead the way. By using generics, it becomes possible:

fn foo<S: AsRef<str>>(names: &[S]) {
	for name in names.iter().map(|s| s.as_ref()) {
		println!("{}", name);
	}
}

Or alternatively using the impl keyword for the trait bound:

fn foo(names: &[impl AsRef<str>]) {
	for name in names.iter().map(|s| s.as_ref()) {
		println!("{}", name);
	}
}

The function above accepts both Vec and slice of String or &str. But notice how, in order to retrieve the string itself, the as_ref() method must be called.

No comments: