为何Rust中&String传入print_a可行,传入MyA::from却失败?
问题解析
首先看你的代码:
fn print_a(a: &str) { println!("this is a: {}", a); } struct MyA { a: String, } impl From<&str> for MyA { fn from(a: &str) -> Self { Self { a: format!("This is a: {}", a), } } } fn main() { let a = "Hello, World!".to_string(); print_a(&a); // 正常运行 let b = MyA::from(&a); // 编译报错 println!("b.a: {}", b.a); }
为什么 print_a(&a) 能正常运行?
当你调用 print_a(&a) 时,&a 的类型是 &String,而函数参数要求的是 &str。Rust 对函数参数有**隐式解引用强制转换(deref coercion)**规则:如果一个类型实现了 Deref trait(比如 String 实现了 Deref<Target=str>),那么当需要该目标类型的引用时,Rust 会自动将原类型的引用解引用为目标类型的引用。所以这里 &String 会被自动转换为 &str,匹配函数参数要求。
为什么 MyA::from(&a) 无法工作?
From trait 的方法调用遵循严格的 trait 解析规则,不会自动应用解引用强制转换。我们的代码只实现了 From<&str> for MyA,而传入的 &a 是 &String 类型——这和 &str 是两个不同的类型,Rust 找不到对应的 From 实现,因此编译报错。
解决方法
你已经知道可以用 a.as_str() 显式转换,另外也可以用 &*a(先解引用 &String 得到 String,再取引用得到 &str),效果是一样的:
let b = MyA::from(&*a);
内容的提问来源于stack exchange,提问作者Rodolfo
相关产品推荐
相关产品推荐

