gpt4 book ai didi

rust - 在宏中调用 `stringify!`

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

此宏在调用时编译:

macro_rules! remote_optional {
($remote:ident with=$def:ident $def_str:expr) => {
impl $def {
fn deserialize_option<'de, D>(deserializer: D) -> Result<Option<$remote>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Wrapper(#[serde(with = $def_str)] $remote);

let v: Option<Wrapper> = Option::deserialize(deserializer)?;
Ok(v.map(|Wrapper(a)| a))
}
}
}
}

这个没有:

macro_rules! remote_optional {
($remote:ident with=$def:ident) => {
impl $def {
fn deserialize_option<'de, D>(deserializer: D) -> Result<Option<$remote>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Wrapper(#[serde(with = stringify!($def))] $remote);

let v: Option<Wrapper> = Option::deserialize(deserializer)?;
Ok(v.map(|Wrapper(a)| a))
}
}
}
}

这是因为 stringify!($def) 被传递到 #[serde(...)] 属性未计算。

有什么实际的解决方法吗?

最佳答案

可以将两个参数的宏转发到三个参数的宏,扩展 def 标识符吗?

macro_rules! remote_optional {
// The one that doesn't work (two arguments)
// forwards to the one that *does* work, expanding the
// string.
($remote:ident with=$def:ident) => {
remote_optional!($remote, with=$def, stringify!($def));
};

// The macro that *does* work
($remote:ident with=$def:ident $def_str:expr) => {
impl $def {
fn deserialize_option<'de, D>(deserializer: D) -> Result<Option<$remote>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Wrapper(#[serde(with = $def_str)] $remote);

let v: Option<Wrapper> = Option::deserialize(deserializer)?;
Ok(v.map(|Wrapper(a)| a))
}
}
};
}

我们还可以考虑将三个参数的宏作为实现细节。

小的、孤立的概念验证:

macro_rules! my_macro {
($x:expr, $y:expr) => {
my_macro!($x, $y, stringify!($x + $y));
};

($x:expr, $y:expr, $msg:expr) => {
println!("{} + {} = {}", $x, $y, $msg);
};
}


fn main() {
my_macro!(3, 2); // 3 + 2 = 3 + 2
}

关于rust - 在宏中调用 `stringify!`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55582838/

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