Rust 使用运行时定义的成员标记联合

Rust 使用运行时定义的成员标记联合,rust,Rust,我正在开发一个小型解释器,我想在堆栈上表示一些类型,其他类型是指针。下面是C++中的情况: enum{ 零型, INT_类型, 参考类型开始, } 联合数据 { 国际价值; 无效*obj_val } 结构对象 { 大小\u t\u类型\u id; 数据(u)数据;; } \u type\u id充当结构其余部分的标记。整数、布尔、nils等可以在堆栈上传递,而字符串和对象等较大的东西可以通过引用传递 解释器将在运行时创建新类型,这就是REF\u START\u TYPE的作用。创建新类型时,我

我正在开发一个小型解释器,我想在堆栈上表示一些类型,其他类型是指针。下面是C++中的情况:

enum{
零型,
INT_类型,
参考类型开始,
}
联合数据
{
国际价值;
无效*obj_val
}
结构对象
{
大小\u t\u类型\u id;
数据(u)数据;;
}
\u type\u id
充当结构其余部分的标记。整数、布尔、nils等可以在堆栈上传递,而字符串和对象等较大的东西可以通过引用传递

解释器将在运行时创建新类型,这就是
REF\u START\u TYPE
的作用。创建新类型时,我们将向某个内部计数器添加一个值,该值将成为下一个类型id,并且该类型应为指针


我怎样才能在Rust中表示这样的东西?枚举类型看起来很棒,但它们似乎不允许扩展。未标记的工会似乎在很大程度上是一种在制品,没有多少帮助。有没有什么方法可以在允许运行时扩展的同时获得这种堆栈上行为(从而减少数学操作期间的大量分配)

听起来你想要像这样的东西

enum Object {
    Nil,
    Int(i32),
    Runtime(TypeId, RuntimeType),
}
您可以确保
RuntimeType
只包含指针,或者选择立即将其装箱(
Runtime(TypeId,box),
),但最终结果相同

如果它包含一个
,则此结构在64位机器上会占用24个字节。不幸的是,我没有办法通知编译器
TypeId
和枚举的判别式应该位于同一位置。如果您的测量结果显示解引用比额外堆栈大小小,则可以选择将
TypeId
移动到
框中。这取决于您直接嵌入到枚举中的其他类型。例如,
Vec
是相当于堆栈空间的三个指针。如果包括这些,您就可以内联更多的值

诀窍是:什么是
RuntimeType
?你对这个问题的描述还不够让我猜。它可能是一个具体的类型,也可能最终成为一个装箱的trait对象

一个更完整的例子:

struct RuntimeType;
type TypeId = u64;

enum Object {
    Nil,
    Int(i32),
    Runtime(TypeId, RuntimeType),
}

impl Object {
    fn type_id(&self) -> TypeId {
        use Object::*;

        match *self {
            Nil => 0,
            Int(..) => 1,
            Runtime(id, ..) => id,
        }
    }
}

fn main() {}

C也不支持联合类型的运行时扩展,所以我不认为这里的问题是真正的特定于rust的。但如果你试图避免的是分配,那么看看例如。