关于Rust函数传参自动解引用规则的常见疑问
我们已知String实现了Deref trait,解引用后可以得到&str,对应实现如下:
impl ops::Deref for String { type Target = str; #[inline] fn deref(&self) -> &str { unsafe { str::from_utf8_unchecked(&self.vec) } } }
- 如下代码可以正常运行,原因是符合Rust的自动解引用规则:当给需要
&str参数的函数传入&String时,Rust会自动沿着&String -> &str的解引用链做隐式转换,类型完全匹配。
fn uppercase(s: &str) -> String { s.to_uppercase() } fn main() { let s = String::from("hello"); assert_eq!(uppercase(&s), "HELLO"); }
- 第二个代码片段无法运行的原因:
自动解引用强制转换仅适用于引用类型之间的隐式转换,不会自动给所有权值取引用。你传入的实参是持有所有权的String类型值,而形参需要的是&str引用,Rust不会自动给String取引用再做解引用转换,因此类型不匹配,编译报错。
fn uppercase(s: &str) -> String { s.to_uppercase() } fn main() { let s = String::from("hello"); assert_eq!(uppercase(s), "HELLO"); }
- 第三个代码片段无法运行的原因:
自动解引用只能做引用层面的无开销转换,不会隐式执行需要转移所有权或者拷贝数据的操作。你传入的实参是&String不可变引用,而形参需要拿到String的所有权,要把&String转成String需要手动执行解引用移动或者调用clone方法,这一步不会自动发生,因此类型不匹配,编译报错。
fn uppercase(s: String) -> String { s.to_uppercase() } fn main() { let s = String::from("hello"); assert_eq!(uppercase(&s), "HELLO"); }
内容的提问来源于stack exchange,提问作者gaoxinge
相关产品推荐
相关产品推荐

