是否可以判断一个字段是否是某种类型或在过程宏中实现某种方法?

bla*_*fsa 6 rust rust-proc-macros

我创建了一个实现特征的程序宏,但为了使其工作,我需要获取每个字段的原始字节。问题是如何获取字段的字节取决于字段的类型。

有没有某种方法可以测试某个函数是否存在于某个字段以及它是否不尝试另一个函数?

例如这样的事情:

if item.field::function_exist {
    //do code
} else {
    //do other code
}
Run Code Online (Sandbox Code Playgroud)

目前,我正在考虑创建另一个特征/成员函数,我只需为所有原语创建它,并为更大的字段(例如结构)创建一个程序宏。例如:

if item.field::as_bytes().exists {
    (&self.#index).as_bytes()
} else {
    let bytes = (&self.#index).to_bytes();
    &bytes
}
Run Code Online (Sandbox Code Playgroud)

对于字符串,它有as_bytes成员函数,而对于字符串则i32没有。这意味着当结构的成员字段不是字符串时,我需要额外的代码。我可能需要 amatch而不是 an if,但是if对于这个例子来说就足够了。

She*_*ter 4

\n

是否可以判断一个字段是否是某种类型或在过程宏中实现某种方法?

\n
\n

不它不是。

\n

宏对Rust 代码的抽象语法树 (AST)进行操作。这意味着您基本上只是获取用户输入的字符。

\n

如果用户代码具有类似 的内容type Foo = Option<Result<i32, MyError>>,并且您处理一些使用 的代码Foo,则宏将不知道它“确实”是一个Option.

\n

即使它确实知道类型,了解可用的方法也会更加困难。未来的板条箱可以创建向现有类型添加方法的特征。在程序宏运行时,这些包可能还没有被编译。

\n
\n

我正在考虑创建另一个特征/成员函数,我只需为所有原语创建它,并为更大的字段(例如结构)创建一个程序宏。

\n
\n

这是正确的解决方案。如果您查看任何现有的常用程序宏,就会发现它正是这样做的。这允许编译器执行编译器想要执行的操作。

\n

这对于可维护性来说也更好 \xe2\x80\x94 现在这些原始实现位于标准 Rust 文件中,而不是嵌入宏内部。更容易阅读和调试。

\n

你的箱子里会有这样的东西:

\n
// No real design put into this trait\ntrait ToBytes {\n    fn encode(&self, buf: &mut Vec<u8>);\n}\n\nimpl ToBytes for str {\n    fn encode(&self, buf: &mut Vec<u8>) {\n        buf.extend(self.as_bytes())\n    }\n}\n\n// Other base implementations\n
Run Code Online (Sandbox Code Playgroud)\n

您的程序宏将以简单的方式实现这一点:

\n
#[derive(ToBytes)]\nstruct Foo {\n    a: A,\n    b: B,\n}\n
Run Code Online (Sandbox Code Playgroud)\n

变成

\n
impl ToBytes for Foo {\n    fn encode(&self, buf: &mut Vec<u8>) {\n        ToBytes::encode(&self.a, buf);\n        ToBytes::encode(&self.b, buf);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

作为一个具体的例子,Serde做了同样的事情,有多种方式来序列化和从二进制数据:

\n\n