提问人:kalkronline 提问时间:9/8/2023 最后编辑:kmdrekokalkronline 更新时间:9/9/2023 访问量:230
为什么默认情况下没有调整特征大小?
Why aren't traits Sized by default?
问:
我定义了一个特征,其中包含一个返回的函数,但会产生错误:ReadTag
Self
trait ReadTag {
fn read_out(buf: &mut &[u8]) -> Option<Self>;
}
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> src/lib.rs:2:37
|
2 | fn read_out(buf: &mut &[u8]) -> Option<Self>;
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
通过添加为超特征来修复错误,这是有道理的,但为什么默认值不像函数那样呢?Sized
Sized
fn my_sized<T>(t: T) { } // all good, Sized is opt-out :)
fn my_unsized<T: ?Sized>(t: T) { } // not allowed
答:
9赞
kmdreko
9/8/2023
#1
关于 Sized
的文档介绍了为什么它不是 traits 的默认/隐式绑定:
特征没有隐式绑定,因为这与特征对象不兼容,根据定义,特征对象需要与所有可能的实现者一起工作,因此可以是任何大小。
Sized
虽然 Rust 会让你绑定到一个特征,但你以后将无法使用它来形成一个特征对象:
Sized
trait Foo { } trait Bar: Sized { } struct Impl; impl Foo for Impl { } impl Bar for Impl { } let x: &dyn Foo = &Impl; // OK // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot // be made into an object
默认情况下不允许听起来确实是一个糟糕的选择。dyn Trait
至于为什么其他所有东西(函数、结构、枚举、类型等)都是默认的,需要更多的猜测。在大多数其他上下文中,可能需要类型可能更为常见,并且到处都需要将是一个嘈杂的负担。后者(在需要未调整大小的类型时放宽约束)是两者中最不麻烦的。这个答案证实了这一点。Sized
Sized
T: Sized
T: ?Sized
评论