首页 文章

无法在使用该库的可执行文件中的库中导入宏

提问于
浏览
0

我在从另一个箱子中获取宏来使用Rust时遇到了很多麻烦 . 我的lib.rs文件如下所示:

#[macro_use]
extern crate session_types;

mod main;

这是我的main.rs的简化部分,演示正确使用 offer! 宏:

use session_types::*;

type Server = Offer<Choose<Var<Z>, Var<Z>>, Choose<Var<Z>, Var<Z>>>;

struct Foo;

impl Foo {
    fn server(&self, c: Chan<(), Rec<Server>>) {
        let mut c = c.enter();
        loop {
            c = offer!{ c,
                LEFT_BRANCH => c.sel1().zero(),
                RIGHT_BRANCH => c.sel2().zero()
            };
        }
    }
}

我知道编译器能够扩展 offer! ,因为我在该宏内部的块中调试了代码,并且我得到关于该宏中未使用的变量的警告,如下所示:

<session_types macros>:1:1: 5:16 note: in expansion of offer!
src/main.rs:107:21: 133:14 note: expansion site
<session_types macros>:3:53: 3:57: warning: unused variable: 'right', #[warn(unused_variables)] on by default
<session_types macros>:3 Branch:: Left ( $id ) => $code, Branch:: Right ( $id ) => offer! {

这显然包括宏的一部分 . 但是,我收到编译错误,说明在使用它们的行时,宏 offer! 未定义 .

src/main.rs:107:21: 133:14 note: in this expansion of offer! (defined in <session_types macros>)
src/main.rs:57:17: 57:22 error: macro undefined: 'offer!'
src/main.rs:57             c = offer!{ c,
                               ^~~~~
src/main.rs:107:21: 107:26 error: macro undefined: 'offer!'
src/main.rs:107             night = offer!{ night,

注意:这发生在编译器的夜间分支上 .

1 回答

  • 3

    此示例重现您的问题:

    Cargo.toml

    [package]
    name = "mac"
    version = "0.1.0"
    authors = ["An Devloper <an.devloper@example.com>"]
    
    [dependencies]
    lazy_static = "0.1.14"
    

    src/lib.rs

    #[macro_use]
    extern crate lazy_static;
    
    lazy_static! {
        pub static ref LIBRARY_VERSION: u8 = 1;
    }
    
    pub fn adder(a: u8, b: u8) -> u8 { a + b }
    

    src/main.rs

    extern crate mac;
    
    lazy_static! {
        static ref EXECUTABLE_VERSION: u8 = 1;
    }
    
    fn main() {
        println!("Adder version {} (lib version {})", *EXECUTABLE_VERSION, *mac::LIBRARY_VERSION);
        println!("Result: {}", mac::adder(1, 2));
    }
    

    问题是宏观包含物不能跨越板条传递 . 将它们包含在库文件中不会使它们在使用您的库的任何下游包中都可用 . 这样可以完全排除水中的任何选择性使用;想想在一个有20个依赖项的项目中你会拥有多少项(每个项都有自己的依赖项)!

    您还需要在可执行文件中明确包含宏,因为它是一个不同的包:

    #[macro_use]
    extern crate lazy_static;
    // ... rest of above src/main.rs
    

相关问题