gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 08:15:33 26 4
gpt4 key购买 nike

我创建了一个实现特征的过程宏,但为了让它工作,我需要获取每个字段的原始字节。问题是如何获取字段的字节因字段类型而异。

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

例如像这样:

if item.field::function_exist {
//do code
} else {
//do other code
}

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

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

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

最佳答案

Is it possible to tell if a field is a certain type or implements a certain method in a procedural macro?

不,不是。

宏在 abstract syntax tree (AST) 上运行的 rust 代码。这意味着您基本上只获取用户输入的字符。

如果用户代码有类似 type Foo = Option<Result<i32, MyError>> 的内容,然后您处理一些使用 Foo 的代码,宏不会知道它“真的”是一个 Option .

即使它确实知道类型,但要知道可用的方法会更加困难。 future 的 crate 可以创建特征,将方法添加到现有类型。在过程宏运行的时间点,这些箱子可能甚至还没有被编译。

I am looking at creating another trait/member function that I just have to create for all primitives and create a procedural macro for larger fields such as structs.

这是正确的解决方案。如果您查看任何现有的使用良好的程序宏,它就是这样做的。这允许编译器执行编译器打算执行的操作。

这对于可维护性也更好——现在这些原始实现存在于标准 Rust 文件中,而不是嵌入在宏中。更易于阅读和调试。

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

// No real design put into this trait
trait ToBytes {
fn encode(&self, buf: &mut Vec<u8>);
}

impl ToBytes for str {
fn encode(&self, buf: &mut Vec<u8>) {
buf.extend(self.as_bytes())
}
}

// Other base implementations

并且您的程序宏将以直接的方式实现它:

#[derive(ToBytes)]
struct Foo {
a: A,
b: B,
}

成为

impl ToBytes for Foo {
fn encode(&self, buf: &mut Vec<u8>) {
ToBytes::encode(&self.a, buf);
ToBytes::encode(&self.b, buf);
}
}

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

关于rust - 是否可以判断一个字段是否是某种类型或在过程宏中实现某种方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55451295/

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