AnyMap 的实现和`struct Port(u32);` 的运行时开销
Implementation of AnyMap and runtime overhead of `struct Port(u32);`
我正在阅读“Rust 的 24 天”,the example of AnyMap
usage 让我大吃一惊。考虑以下代码:
#[deriving(Show)]
struct Port(u32);
#[deriving(Show)]
struct ConnectionLimit(u32);
它说:
Here the Port
and ConnectionLimit
types are abstractions over the
underlying integer (with no overhead at runtime!).
很好,我明白这是如何实现的。在编译期间检查所有类型,在运行时我们只有 u32。但在这种情况下,如何创建从 TypeId
到 Box<Any>
的映射?以及如何将 Any 转换为任何子类型,例如 u32?
source code on AnyMap
比较复杂,涉及到很多元编程。它是如何工作的?也许“Rust 的 24 天”只是一个错误,Port
和 ConnectionLimit
实际上有运行时开销?
实际上,在 C、C++ 和其他系统语言中,具有相同内存表示的不同类型是很常见的。
记忆中:
- a
u32
是 4 个连续的内存字节
- a
Port
是 4 个连续的内存字节
- a
ConnectionLimit
是 4 个连续的内存字节
值得注意的是,与许多其他语言相比,这些类型的每个实例都没有 "virtual table" 或其他无关信息存储在内存中。
至于AnyMap
,在您将对象存储在映射中的位置,编译器知道对象的类型,因此可以提供正确的TypeId
。这必须与对象数据一起珍贵地携带,因为一旦丢失就无法恢复。
我正在阅读“Rust 的 24 天”,the example of AnyMap
usage 让我大吃一惊。考虑以下代码:
#[deriving(Show)]
struct Port(u32);
#[deriving(Show)]
struct ConnectionLimit(u32);
它说:
Here the
Port
andConnectionLimit
types are abstractions over the underlying integer (with no overhead at runtime!).
很好,我明白这是如何实现的。在编译期间检查所有类型,在运行时我们只有 u32。但在这种情况下,如何创建从 TypeId
到 Box<Any>
的映射?以及如何将 Any 转换为任何子类型,例如 u32?
source code on AnyMap
比较复杂,涉及到很多元编程。它是如何工作的?也许“Rust 的 24 天”只是一个错误,Port
和 ConnectionLimit
实际上有运行时开销?
实际上,在 C、C++ 和其他系统语言中,具有相同内存表示的不同类型是很常见的。
记忆中:
- a
u32
是 4 个连续的内存字节 - a
Port
是 4 个连续的内存字节 - a
ConnectionLimit
是 4 个连续的内存字节
值得注意的是,与许多其他语言相比,这些类型的每个实例都没有 "virtual table" 或其他无关信息存储在内存中。
至于AnyMap
,在您将对象存储在映射中的位置,编译器知道对象的类型,因此可以提供正确的TypeId
。这必须与对象数据一起珍贵地携带,因为一旦丢失就无法恢复。