为何Rust中String的deref()返回&str,而*操作符返回str?
为什么
*owned得到str而不是&str? 先看你的测试代码:
let owned = "test".to_string(); // owned type is String let s1 = owned.deref(); // s1 type is &str let s2 = *owned; // s2 type is str
核心差异来自Deref trait的定义和*操作符的实际行为:
String实现的Deref中,deref()方法直接返回&str类型,所以调用owned.deref()时,你拿到的就是一个指向字符串切片的引用,这也是s1类型为&str的原因。- 当你使用
*owned时,Rust会自动触发deref()调用得到&str,然后再对这个引用执行解引用操作——等价于*(owned.deref()),这一步得到的是str类型本身,而非引用。
问题出在str是动态大小类型(DST):它的长度只有运行时才能确定,Rust不允许直接将动态大小类型绑定到栈变量(栈变量需要编译时确定大小),因此编译器会报错“str类型的值大小在编译时无法确定”。
那为什么平时写println!("{}", *owned)不会报错?因为Rust会自动做隐式引用转换:当函数需要&str时,它会自动把*owned返回的str转换成&str,相当于帮你自动加了一个&。
如果想让s2和s1类型一致,只需手动取一次引用:
let s2 = &*owned; // s2 type is &str
或者显式指定类型,编译器会自动补全引用转换:
let s2: &str = *owned;
内容的提问来源于stack exchange,提问作者Defisher
相关产品推荐
相关产品推荐

