关于std::marker::Sized trait的疑问:为何String未实现该trait?
关于String与Sized trait的误解纠正
首先明确:String是完全实现了Sized trait的,你的认知里“String未实现Sized”是错误的,这是矛盾的核心来源。
验证事实:可以通过简单代码确认
use std::mem; fn main() { // 编译时就能确定String的大小,64位系统下是24字节 println!("Size of String: {} bytes", mem::size_of::<String>()); // 接收Sized类型的函数可以正常接收String takes_sized(String::from("hello")); } fn takes_sized<T: Sized>(_: T) {}这段代码能正常编译运行,说明
String符合Sized的要求。你的认知偏差点:混淆了类型自身的栈上大小和类型指向的堆内存大小
Sizedtrait的定义就是“编译时已知固定大小的类型”,这里的大小指的是类型本身在栈上占用的空间,和它引用、指向的堆内存完全无关。String内部包含一个Vec,而Vec的结构是(指针, 长度, 容量)三个固定大小的字段,整个String结构体的大小在编译时就确定了,完全满足Sized的条件。区分动态大小类型(DST)与Sized类型
你提到的dyn Clone属于动态大小类型(DST),这类类型的大小在编译时无法确定(不同的Clone实现者自身大小可能不同),所以不实现Sized;而String是具体的、确定的类型,自身大小固定,属于Sized类型,自然可以声明为局部变量——栈帧只需要预留String本身的固定空间即可,堆上的内容不影响栈帧的大小计算。补充说明
Rust中几乎所有具体类型(除了DST,比如str、[T]、dyn Trait)都会被编译器自动推导实现Sized,不需要手动实现。
内容的提问来源于stack exchange,提问作者Gerhard77
相关产品推荐
相关产品推荐

