Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 宏规则只匹配第一个模式_Macros_Rust - Fatal编程技术网

Macros 宏规则只匹配第一个模式

Macros 宏规则只匹配第一个模式,macros,rust,Macros,Rust,我为sym链接文件编写了一个宏。起初我只有第一个模式,但后来我想不必一直写“&format!”就好了 因此,根据这些模式: macro_rules! syml { ($a:expr, $b:expr) => { Command::new("ln").args(&["-s", $a, $b]) }; ( ($a:expr, $($x:expr),+), ($b:expr, $($y:expr),+) ) => { Comm

我为sym链接文件编写了一个宏。起初我只有第一个模式,但后来我想不必一直写“&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));
但是到目前为止,每次只有第一个模式匹配,所以我得到了
不匹配的类型
错误,比如
预期引用,find 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])
    }
}
()

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

syml!(("{}", from), "to");
syml!("from", ("{}", to));
这可以通过添加新案例(按顺序)简单地解决。(我不知道是否有可能排除元组/字符串匹配,但我有兴趣看到任何解决方案。)


()

不是宏专家,所以我只想简单指出两点:(1)元组是一个表达式,因此“(x,y)”可以匹配
$a:expr
,(2)我相信这些模式是按顺序尝试的。。。您是否尝试过先放置更具体的模式?与问题无关,但标准库有一个函数。当然,元组是一个表达式!我完全错过了,谢谢。还要感谢@MatthieuM。感谢您对我的两个未覆盖测试用例进行编辑并提供修复!一个规则更少的解决方案确实很有趣。也许我可以在深入研究铁锈宏之后找到一个;我真的很少玩宏:)
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])
    }
}