如何创建将输入转换为元组的宏?
How do I create a macro that transforms inputs into a tuple?
我想尽可能避免创建许多带编号的函数和重复代码。我正在编写一个程序来解析包含如下行的配置文件,我想使用一些辅助函数来简化解析它的逻辑。
我想获得有关处理此问题的惯用 Rust 方法的建议,以避免代码重复,同时保持其可读性。我最好的猜测是,如果我可以使用一个宏,它可以以某种方式将输入转换成一个产生元组的块,但在包括迭代和转换步骤的同时不知道如何编写它。
示例输入
attribute-name
1 2
other-attribute
3 4 5
当前解析实现
/// Splits `s` into two values, using `pattern` to find the split. If not enough values
/// are present, `missing_err` is returned.
/// It then `transform`s each entry, returning the result as a tuple
fn split_str_into_2<'a, T, E>(
s: &'a str,
pattern: &str,
transform: &dyn Fn(&str) -> T,
missing_err: &E,
) -> Result<(T, T), E> where E: Copy {
let mut split = s.splitn(2, pattern);
Ok((
transform(split.next().ok_or_else(|| *missing_err)?),
transform(split.next().ok_or_else(|| *missing_err)?),
))
}
/// Same as above but parses into a tuple of 3
fn split_str_into_3<'a, T, E>( ...
调用代码
let (width, height) = split_str_into_2(
input_line, " ", |entry| i32::from_str_radix(entry, 10), &MyError::new("Missing number entry"))?;
我不知道你的确切用途,但如果你想将迭代器收集到元组中,一种可能性是 Itertools::collect_tuple
。
目前已为 tuples up to length 4 实施。如果您需要更多元素,您可以尝试调整 itertools
中采用的方法或在项目中提交 issue/PR。
我想尽可能避免创建许多带编号的函数和重复代码。我正在编写一个程序来解析包含如下行的配置文件,我想使用一些辅助函数来简化解析它的逻辑。
我想获得有关处理此问题的惯用 Rust 方法的建议,以避免代码重复,同时保持其可读性。我最好的猜测是,如果我可以使用一个宏,它可以以某种方式将输入转换成一个产生元组的块,但在包括迭代和转换步骤的同时不知道如何编写它。
示例输入
attribute-name
1 2
other-attribute
3 4 5
当前解析实现
/// Splits `s` into two values, using `pattern` to find the split. If not enough values
/// are present, `missing_err` is returned.
/// It then `transform`s each entry, returning the result as a tuple
fn split_str_into_2<'a, T, E>(
s: &'a str,
pattern: &str,
transform: &dyn Fn(&str) -> T,
missing_err: &E,
) -> Result<(T, T), E> where E: Copy {
let mut split = s.splitn(2, pattern);
Ok((
transform(split.next().ok_or_else(|| *missing_err)?),
transform(split.next().ok_or_else(|| *missing_err)?),
))
}
/// Same as above but parses into a tuple of 3
fn split_str_into_3<'a, T, E>( ...
调用代码
let (width, height) = split_str_into_2(
input_line, " ", |entry| i32::from_str_radix(entry, 10), &MyError::new("Missing number entry"))?;
我不知道你的确切用途,但如果你想将迭代器收集到元组中,一种可能性是 Itertools::collect_tuple
。
目前已为 tuples up to length 4 实施。如果您需要更多元素,您可以尝试调整 itertools
中采用的方法或在项目中提交 issue/PR。