如何用单个Rust函数同时接收&str、String和&String类型参数?
如何在Rust中编写支持&str、String和&String的单一函数
当然可以!在Rust里,我们可以借助AsRef<str> trait来实现这个需求——它专门为这类「可以转换成&str的类型」设计,你的三种目标类型(&str、String、&String)都自动实现了这个trait,完美适配。
实现代码
fn accept_all_strings<S: AsRef<str>>(value: S) { // 转换为&str,所有传入类型都能无缝处理 let str_ref = value.as_ref(); println!("value: {}", str_ref); } fn main() { let str_foo = "foo"; let string_foo = String::from("foo"); accept_all_strings(str_foo); // 直接传入&str字面量 accept_all_strings(&string_foo); // 传入String的引用 accept_all_strings(string_foo); // 传入String的所有权(如果后续不需要使用string_foo的话) }
为什么这样可行?
&str本身就是AsRef<str>的实现,调用as_ref()直接返回自身,没有额外开销。String实现了AsRef<str>,调用as_ref()会返回其内部的&str引用,无需内存分配。&String同样实现了AsRef<str>,会自动解引用并返回内部的&str。
额外说明
如果你的函数内部需要拥有String的所有权(而不仅仅是引用),可以改用Into<String>作为约束——不过这样会对&str和&String触发内存分配(因为要克隆成新的String),而String本身会直接转移所有权:
fn accept_all_strings_owned<S: Into<String>>(value: S) { let owned_string = value.into(); println!("owned value: {}", owned_string); }
但如果只是读取字符串内容,AsRef<str>是更高效的选择,能避免不必要的内存操作。
内容的提问来源于stack exchange,提问作者Ringo Leese
相关产品推荐
相关产品推荐

