gpt4 book ai didi

rust - 带有运行时定义成员的标记联合

转载 作者:行者123 更新时间:2023-11-29 08:14:20 25 4
gpt4 key购买 nike

我正在开发一个小型解释器,我想在堆栈上表示某些类型,而其他类型是指针。这是它在 C++ 中的样子:

enum {
NIL_TYPE,
INT_TYPE,
REF_TYPE_START,
}

union Data
{
int int_val;
void *obj_val
}

struct Object
{
size_t _type_id;
Data _data;
}

_type_id 充当结构其余部分的标记。整数、 bool 值、nils 等可以在堆栈上传递,而字符串和对象等较大的东西可以通过引用传递。

解释器将在运行时创建新类型,这就是 REF_START_TYPE 的用途。当创建一个新类型时,我们将向某个内部计数器添加一个值,该值将成为下一个类型 ID,并且该类型应该是一个指针。

我如何在 Rust 中表示这样的东西?枚举类型看起来很棒,但它们似乎不允许扩展。 Untagged unions 似乎是一个 WIP,并没有太大帮助。有什么办法可以获得这种堆栈行为(从而减少数学运算期间的大量分配),同时仍然允许运行时扩展?

最佳答案

听起来你想要这样的东西

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

您可以确保 RuntimeType仅包含一个指针或选择立即将其装箱 ( Runtime(TypeId, Box<RuntimeType>), ),但最终结果相同。

如果它包含 Box ,这个结构在 64 位机器上占用 24 个字节。不幸的是,我不知道如何通知编译器 TypeId并且枚举的判别式应该位于同一位置。您可以改为选择移动 TypeId进入Box<RuntimeType>如果您的测量结果表明取消引用没有额外堆栈大小那么糟糕。这一切都非常可塑,具体取决于您直接嵌入到枚举中的其他类型。例如,Vec是 3 个指针的堆栈空间。如果包含在内,您可以内联更多值。

技巧变成:什么是RuntimeType ?你没有描述足够的问题让我猜测。它可能是具体类型,也可能最终成为装箱特征对象。

一个更完整的例子:

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() {}

关于rust - 带有运行时定义成员的标记联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45112589/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com