gpt4 book ai didi

macros - 宏规则只匹配第一个模式

转载 作者:行者123 更新时间:2023-11-29 07:58:46 25 4
gpt4 key购买 nike

我为符号链接(symbolic link)文件写了一个宏。起初我只有第一个模式,但后来认为不必写“&format!”就好了。一直。

所以有了这些模式:

macro_rules! syml {
($a:expr, $b:expr) => {
Command::new("ln").args(&["-s", $a, $b])
};
( ($a:expr, $($x:expr),+), ($b:expr, $($y:expr),+) ) => {
Command::new("ln").args(&["-s", &format!($a, $($x),+), &format!($b, $($y),+)])
}
}

我想匹配这些情况:

syml!("from", "to");
syml!(("{}", from), "to");
syml!("from", ("{}", to));
syml!(("{}", from), ("{}", to));
syml!(("{}{}", from, here), ("{}{}", to, there));

但到目前为止,每次只有第一个模式匹配,所以我得到了不匹配的类型错误,比如expected reference, found tuple

我不明白为什么即使对于最后两个示例,它也会尝试匹配第一个模式而不是第二个。

最佳答案

正如@MatthieuM 在评论中指出的那样,元组是一个表达式,宏规则按顺序尝试。

所以在你的情况下:

macro_rules! syml {
($a:expr, $b:expr) => {
Command::new("ln").args(&["-s", $a, $b])
};
( ($a:expr, $($x:expr),+), ($b:expr, $($y:expr),+) ) => {
Command::new("ln").args(&["-s", &format!($a, $($x),+), &format!($b, $($y),+)])
}
}

第一个规则将始终匹配第二个规则。解决方案是交换它们:

macro_rules! syml {
( ($a:expr, $($x:expr),+), ($b:expr, $($y:expr),+) ) => {
Command::new("ln").args(&["-s", &format!($a, $($x),+), &format!($b, $($y),+)])
};
($a:expr, $b:expr) => {
Command::new("ln").args(&["-s", $a, $b])
}
}

( Playground )

上面没有涵盖您混合元组和字符串的两个测试用例:

syml!(("{}", from), "to");
syml!("from", ("{}", to));

这可以通过添加新案例(按顺序)简单地解决。 (我不知道是否可以分解元组/字符串匹配,但有兴趣查看任何解决方案。)

macro_rules! syml {
( ($a:expr, $($x:expr),+), ($b:expr, $($y:expr),+) ) => {
Command::new("ln").args(&["-s", &format!($a, $($x),+), &format!($b, $($y),+)])
};
( $a:expr, ($b:expr, $($y:expr),+) ) => {
Command::new("ln").args(&["-s", $a, &format!($b, $($y),+)])
};
( ($a:expr, $($x:expr),+), $b:expr ) => {
Command::new("ln").args(&["-s", &format!($a, $($x),+), $b])
};
($a:expr, $b:expr) => {
Command::new("ln").args(&["-s", $a, $b])
}
}

( Playground )

关于macros - 宏规则只匹配第一个模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42666203/

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