【问题标题】:How to set dependencies for a macro in Rust?如何在 Rust 中为宏设置依赖项?
【发布时间】:2020-12-06 02:41:19
【问题描述】:

我在一个 crate 中编写了一个宏,并将它导入到一个主项目的 main 函数中。

宏依赖于:

use chrono::{Utc, Local, DateTime, Date};

目前我在主项目的 Cargo.toml 中包含依赖项。

我是否需要对所有主要项目都这样做?或者我可以在宏箱的 Cargo.toml 中声明依赖吗?

//lib.rs //Mymacro 
#[macro_export]
macro_rules! time {
    () => {
        use chrono::{Utc, Local, DateTime, Date};
        let local_datetime: DateTime<Local> = Local::now();
        println!("{:?}",local_datetime);
    }
}
//main.rs // main project
extern crate Mymacro;

#[macro_use]
fn main() {
    time!();
}

// Cargo.html 
[dependencies] 
chrono=""

【问题讨论】:

    标签: rust


    【解决方案1】:

    我是否需要对所有主要项目都这样做?或者我可以在宏箱的 Cargo.toml 中声明依赖吗?

    您可以通过 (1) 让宏调用库中的函数或 (2) 重新导出 chrono(部分或全部)。


    假设我们有一个工作区,有一个 libbin 板条箱。

    [workspace]
    members = [
        "bin",
        "lib",
    ]
    

    现在,在 Cargo.tomllib crate 中,您可以将 chrono 作为依赖项包含在内,就像其他方式一样。

    [dependencies]
    chrono = "0.4"
    

    bin 板条箱的 Cargo.toml 仅具有 lib 的依赖关系。

    [dependencies]
    lib = { path = "../lib" }
    

    现在,让我们考虑 main.rsbin crate 中的样子:

    use lib::time;
    
    fn main() {
        time!();
    }
    

    无论你选择哪个选项,它都将保持不变。


    下面的sn-ps代表lib.rs


    库函数

    如果您实际上从未返回任何chrono 特定类型,那么这可能是最简单的。因为您避免完全重新导出 chrono。

    use chrono::{DateTime, Local};
    
    pub fn _time() {
        let local_datetime: DateTime<Local> = Local::now();
        println!("{:?}", local_datetime);
    }
    
    #[macro_export]
    macro_rules! time {
        () => {
            $crate::_time();
        };
    }
    

    如果您不希望 _time 出现在您的库的文档中,那么您可以使用 #[doc(hidden)] 属性。

    重新出口一些物品

    或者,如果您希望所有内容都保留在宏中,则可以重新导出它使用的 chrono 类型,并在宏中的类型前面加上 $crate::

    这样做的缺点是,如果您的 bin crate 需要一个未重新导出的 chrono 类型,那么这可能是一个“烦恼”,因此 bin 将需要依赖于 chrono = "0.4"无论如何。

    pub use chrono::{DateTime, Local};
    
    #[macro_export]
    macro_rules! time {
        () => {
            let local_datetime: $crate::DateTime<$crate::Local> = $crate::Local::now();
            println!("{:?}", local_datetime);
        };
    }
    

    main.rs 中,如果你改为使用use lib::*;,那么你当然不需要在前面加上$crate::,但最好避免使用use lib::*;

    再出口计时码表

    最后,如果你需要 chrono 类型在你的 bin crate 中。然后你也可以用pub extern crate chrono;重新导出整个chrono crate。

    请注意,这一次,您需要在宏中的类型前面加上 $crate::chrono::

    pub extern crate chrono;
    
    #[macro_export]
    macro_rules! time {
        () => {
            let local_datetime: $crate::chrono::DateTime<$crate::chrono::Local> =
                $crate::chrono::Local::now();
            println!("{:?}", local_datetime);
        };
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 2014-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-05
      相关资源
      最近更新 更多