我目前正在学习Rust和C++之间的FFI,我想知道如何重新实现这个枚举->
pub enum Stmt {
Block(BlockStmt),
Empty(EmptyStmt),
Debugger(DebuggerStmt),
With(WithStmt),
Return(ReturnStmt),
Labeled(LabeledStmt),
Break(BreakStmt),
Continue(ContinueStmt),
If(IfStmt),
Switch(SwitchStmt),
Throw(ThrowStmt),
Try(TryStmt),
While(WhileStmt),
DoWhile(DoWhileStmt),
For(ForStmt),
ForIn(ForInStmt),
ForOf(ForOfStmt),
Decl(Decl),
Expr(ExprStmt),
}
在C++中,因为我想在C++和Rust之间传输此枚举的枚举变体。
我已经准备好了一个无字段C++枚举,现在我对如何实现元组字段一无所知。
enum Stmt
{
If,
Try,
For,
With,
Decl,
Expr,
ForOf,
ForIn,
Block,
Empty,
Break,
Throw,
While,
Switch,
Return,
DoWhile,
Labeled,
Debugger,
Continue,
};
提前谢谢——玉。
来源https://rust-lang.github.io/unsafe-code-guidelines/layout/enums.html:
如果使用#[repr(C, u8)]
标记枚举,则布局定义为类型为std::uint8_t
的标记变量,后跟所有变体类型的并集:
struct Stmt {
// Order is important. "Block" is 0, "Empty" is 1, etc.
enum : std::uint8_t {
Block, Empty, Debugger // ...
} tag;
union {
// Types of these are the variant members
BlockStmt block;
EmptyStmt empty;
DebuggerStmt debugger;
// ...
};
};
// And you can convert to a std::variant like so
std::variant<BlockStmt, EmptyStmt, DebuggerStmt, ...>
convert(Stmt v) {
switch (v.tag) {
case Stmt::Block: return { std::move(v.block) };
case Stmt::Empty: return { std::move(v.empty) };
// ...
}
}
(通过更改Stmt::tag
枚举的基础类型,可以将u8
替换为任何int类型。如果使用#[repr(C)]
,则基础类型应为int
(