rust 宏展开忽略内标识`for`和其后的任何

jm81lzqq  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(97)

this question类似,我被编译器宏扩展错误难倒了。
违规代码是:

/// send a command and wait for the response
///
/// 'dirty' macro that relies on outside context
macro_rules! send_and_receive {
    ($cmd: expr, $response_pat:pat => $r_block:block) => {
        send_command(&mut port, $cmd);

        for i in 0..3 {
            match receive_response(&mut port) {
                $response_pat => $r_block,
                r => {
                    eprintln!("got response: {r:?}");
                    continue;
                }
            };
        }
        panic!("missing response");
    }
}

其中预期的参数是一个枚举示例和一个“match like”表达式,如下所示:

send_and_receive!(
    Command::Thing { field: value /* etc */ },
    Response::ThingResponse { response_field1,  /* ... */ } => {
        do_stuff_here();
    }
);
7fyelxc5

7fyelxc51#

问题是宏扩展为“松散表达式”,没有封闭块。
添加它解决了这个问题(因为它创建了一个可以返回的范围),如下所示:

macro_rules! send_and_receive {
    ($cmd: expr, $response_pat:pat => $r_block:block) => {
        {
            send_command(&mut port, $cmd);

            for i in 0..3 {
                match receive_response(&mut port) {
                    $response_pat => $r_block,
                    r => {
                        eprintln!("got response: {r:?}");
                        continue;
                    }
                };
            }
            panic!("missing response");
        }
    }
}

相关问题