gpt4 book ai didi

rust - 我可以在结构体内部调用宏吗?

转载 作者:行者123 更新时间:2023-12-03 11:42:50 27 4
gpt4 key购买 nike

我对Rust还是比较陌生,并且正在使用宏进行锻炼。
目标是在Rust lang中归档某种React-ish语法。
我知道像jsx!(<div />)这样的DSL急剧使用方法,这是一个很好的解决方案,但它涉及另一个主题。我正在寻找中间的东西,更像是Flutter或SwiftUI语法,它们尽可能地利用了 native 语言功能,但仍然呈现了直观的分层代码结构。
在这里,我正在探索使用View宏构造children!结构的想法。
我的主要目的是启用View.children字段来保存任意Arity元组。由于可变参数通用元组在Rust中尚不可用,因此宏似乎是唯一的选择。
参见代码和注释:

struct View<T> {
// children field holds arbitrary nullable data
// but what i really want is Variadic Tuple, sadly not available in rust
children: Option<T>,
}

// `children!` macro is a shorthand for Some(VariadicTuple)
// so to avoid the ugly `Some((...))` double parens syntax.
macro_rules! children {
($($x:expr),+ $(,)?) => (
Some(($($x),*))
);
}

fn main() {
let _view = View {
children: children!(
42,
"Im A String",
View {
children: Some(("foo", "bar")),
},
),
};
}
到目前为止,一切都很好。现在,这是我真正想要进一步优化的最后一部分: View {子代: children!(...) }是否可以在结构体内部调用宏(而不是在 value语法之后的 field:位置),从而消除了冗余写入 children:字段的需要?

最佳答案

是的,没有。您不能完全按照自己的描述创建某些东西,但是可以做非常非常相似的事情。
您可以为View结构实现new函数,如下所示:

struct View<T> {
// children field holds arbitrary Option<data>.
children: Option<T>,
}

impl<T> View<T> {
pub fn new() -> Self {
Self {
children: children!(
42,
"Im A String",
View {
children: Some(("foo", "bar")),
},
)
}
}
}

// `children!` macro is a shorthand for Some(VariadicTuple)
// so to avoid the ugly `Some((...))` double parens syntax.
macro_rules! children {
($($x:expr),+ $(,)?) => (
Some(($($x),*))
);
}
然后要创建一个 View 对象,您可以这样做:
fn main() {
let _view1 = View::new();
let _view2 = View::new();
let _view3 = View::new();

// _view1, _view2, and _view3 are *exactly* the same
}
或者,如果您想添加参数,则对用例进行如下修改:
struct View<T> {
// children field holds arbitrary Option<data>.
children: Option<T>,
}

impl<T> View<T> {
pub fn new(age: i32, string: &str) -> Self {
Self {
children: children!(
age,
string,
View {
children: Some(("foo", "bar")),
},
)
}
}
}

// `children!` macro is a shorthand for Some(VariadicTuple)
// so to avoid the ugly `Some((...))` double parens syntax.
macro_rules! children {
($($x:expr),+ $(,)?) => (
Some(($($x),*))
);
}
然后实现它:
fn main() {
let _view1 = View::new(42, "Im A String");
let _view2 = View::new(35, "Im another string");
let _view3 = View::new(12, "This is yet another string");

// _view1, _view2, and _view3 are *not* the same because they have differing "age" and "string" attributes.
}
如果这不是您想要的,或者想要更多帮助,我会在这里为您提供帮助。

关于rust - 我可以在结构体内部调用宏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63636674/

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