快速回答;C++'s POD types ≈ Rust's 100
然而,还有一些其他相关概念.让我们详细讨论一下!
100 trait个最接近C++中的"POD类型",定义如下:
只需复制位即可复制其值的类型.
通过"复制位",文档基本上意味着memcpy()
位.这包括所有基本类型,例如u32
、f32
、char
和bool
,但用户定义的类型也可以是Copy
.通常情况下,这个特征就是derived:
#[derive(Clone, Copy)]
struct Point {
x: f32,
y: f32,
}
你可能已经注意到Clone
:Clone
trait是Copy
的要求,定义如下:
显式复制对象的能力的一个共同特征.
Clone
表示一个类型"能够以某种方式复制自己",而Copy
则表示该类型"能够通过复制类型的位来复制自己",从而要求更多.
C++回答声明POD类型不包含"构造函数、析构函数和虚成员函数".我们来分析一下Rust 的原因:
Constructors:Rust 没有专用的构造函数方法,而是使用相关函数(C++中的静态方法).每一种类型,甚至所有Copy
种类型,都可以有任意多个关联的函数和方法.在 rust 迹斑斑的情况下,它并不是真正的"豆荚"要求.特别是,即使是Rust的原始类型也有很多方法,比如u32::pow()
.这个限制不适用于Rust .
Destructors:在Rust中,通过从Drop
trait调用drop()
(或者更确切地说:drop()
在作用域末尾自动调用),对象被销毁.Types can't be 103 when they implement the 101 trait! Rust在这里也有类似的限制.
Virtual member functions:在Rust中,virtual不是函数的属性.大多数函数都可以在virtual context中使用,也就是说:它们可以与动态分派一起使用,但Copy
并不能阻止类型在动态分派上下文中使用(用 rust 词来说:被用作trait对象).这部分是由于vptr不存储在类型中,而是存储在指向对象的指针(fat pointers)旁边.这一点不适用于Rust .
然而,你可能需要更多的东西从你的"豆荚类型"比"复制位复制".Rust具有一些附加特性的内置特定特性界限:
100:要求类型不包含任何内部引用.例如,struct Foo<'a>(&'a u32);
不能满足这个特征界限.如果你知道你的类型是'static
,你就没有终身限制,借阅判断也不会给你带来任何问题.
Sized
:要求类型的大小在编译时已知,因此可以存储在堆栈上.这几乎适用于所有类型;只有少数几个罕见的ish例外:[T]
和str
(切片)、dyn MyTrait
(特征对象)以及包含未大小类型作为最后一个字段的 struct (例如Path
).
Send
和Sync
:要求类型可以发送到其他线程,并且可以通过不可变引用(&T
)跨线程共享.这两种特性几乎适用于所有类型.如果该类型包含某种魔法(例如interior mutability、references to something without having a lifetime等),则不会实现它.要求这两个trait 界限可以确保你的类型没有这种魔力.
因此,如果你真的想要very simple, no-magic "bag of bits" type分,这似乎是一个合适的特征/界限集合:
trait Pod: 'static + Copy + Sized + Send + Sync {}
impl<T: 'static + Copy + Sized + Send + Sync> Pod for T {}
对于这些类型,您不会处理移动语义(由于Copy
)或borrow 判断器(由于'static
).
未被发送