繁体   English   中英

如何从rust中导出的板条箱宏引用板条箱中的函数?

[英]How do you refer to functions in a crate from an exported crate macro in rust?

我正在尝试编写一些调试助手宏。 因此,我创建了一个箱子来容纳所有箱子,并使用phase(plugin)从外部引用该箱子:

#[cfg(test)]
#[phase(plugin)]
extern crate debugging;

成功将宏导出到板条箱中。

但是,对于某些工具,我想从包装箱中调用函数,例如:

#[macro_export]
macro_rules! trace(
  {$($arg:tt)*} => {
    {
      extern crate debug;
      let s = ::macros::logger(); // <---- This!
      let _ = s.write_line(format_args!(::std::fmt::format, $($arg)*).as_slice());
    }
  };
)

使用全局名称空间,即。 如果将宏放置到macros.rs中并从板条箱的板条根导入,则:: macros :: logger可以工作。

但是,当宏必须从其自己的板条箱调用调用时,我要在此处实现的目标是相同的。

如果宏正确扩展,我相信:

let s = ::crate_name::logger();

可能是这样做的方法,但是带有宏的板条箱无法以这种方式按名称引用自身。 它产生如下错误:

src/macros.rs:52:15: 52:20 error: failed to resolve. Maybe a missing `extern crate debugging`?
src/macros.rs:52       let s = ::debugging::logger();
                               ^~~~~
src/macros.rs:49:1: 56:2 note: in expansion of trace!
src/file.rs:26:11: 26:29 note: expansion site

...最后,这样我们就可以清楚地知道我要做什么:

crate debugging:
   lib.rs
     fn logger() 
   macros.rs
     macro_rules! trace(...) // <--- Trying to figure out what to put here...

crate foo:
   lib.rs
     #[phase(plugin)] extern crate debugging;
     fn test_thing() {
       trace!("{}", ...); // <--- So debugging::logger() is invoked here
     } 

那么,是否有某种方法可以从宏执行此操作?

现在,正确的做法是使用类似的绝对路径,然后在原始板条箱中进行一些重新导出,以便解析路径。

lib.rs

mod debugging {
    pub use logger;
}

它将顶级功能loggerdebugging::logger 正在做的工作使这种情况更聪明,例如$crate扩展为宏所来自的板条箱的名称(当在外部使用时),或者扩展为零(在内部使用时); 这不一定是最终设计,但正在改进。

对于任何其他发现此问题的人,值得注意的是,您不能在标有相位插件的板条箱中使用。 要在本地导入符号(按照公认的答案),您需要执行以下操作:

#[cfg(test)]
mod debug {
  #[phase(plugin)]
  extern crate debugging;
  extern crate debugging;
  pub use self::debugging::debug;
}

注意双外部箱的调试,因为通常您不希望将语法扩展模块作为代码的一部分导出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM