我刚开始使用Rust,并试图用宏来解决一些不便。首先,派生默认宏不支持const函数,因此它们不支持静态对象。为此,我得到了帮助并修改了这个宏,它运行得很好:
#[macro_export]
macro_rules! define_struct_with_const_defaults {
($v:vis struct $name:ident { $($f_name:ident: $f_type:ty = $f_default:expr),* $(,)? }) => {
#[derive(Clone,Copy)]
$v struct $name {
$(
$f_name: $f_type,
)*
}
impl $name {
pub const fn new() -> $name {
$name {
$(
$f_name: $f_default,
)*
}
}
}
}
}所以我想做的下一件事是在python运行的情况下,为单元测试提供无痛的结构访问。所以我想我可以这样做:
use pyo3::prelude::*;
#[macro_export]
macro_rules! define_struct_with_const_defaults {
($v:vis struct $name:ident { $($f_name:ident: $f_type:ty = $f_default:expr),* $(,)? }) => {
#[derive(Clone,Copy)]
#[pyclass]
$v struct $name {
$(
#[pyo3(get, set)] $f_name: $f_type,
)*
}
impl $name {
pub const fn new() -> $name {
$name {
$(
$f_name: $f_default,
)*
}
}
}
}
}但这是行不通的,抱怨是“在这个范围内找不到属性pyclass”
另一方面,如果我这样做,它会奏效:
use pyo3::prelude::*;
#[pyclass]
struct bar {
baz: i32,
}这超出了我的理解范围。它似乎与嵌套宏有关,我想知道它是否与评估的顺序有关。
最后,我希望有条件地使用配置宏编译pyo3内容,这取决于我是否在单元测试环境中,但我甚至无法做到这一点……
任何帮助都将不胜感激,以了解这里发生了什么。
发布于 2022-11-15 05:51:06
问题可能是宏将在其调用站点插入#[pyclass]。因此,您必须将您的use pyo3::prelude::*;放在那里,或者更好地将完整路径包含在宏中,以避免名称冲突:
#[macro_export]
macro_rules! define_struct_with_const_defaults {
($v:vis struct $name:ident { $($f_name:ident: $f_type:ty = $f_default:expr),* $(,)? }) => {
#[derive(Clone,Copy)]
#[::pyo3::prelude::pyclass]
$v struct $name {
$(
#[pyo3(get, set)] $f_name: $f_type,
)*
}
impl $name {
pub const fn new() -> $name {
$name {
$(
$f_name: $f_default,
)*
}
}
}
}
}https://stackoverflow.com/questions/74439306
复制相似问题