简体   繁体   English

#[cfg(test)] 放在 lib.rs 的顶部有什么作用?

[英]What does #[cfg(test)] do when placed at the top of lib.rs?

I'm writing a Rust library (generated from cargo) with unit tests.我正在编写带有单元测试的 Rust 库(从货物生成)。

I'd like to use the extern crate maplit in my unit tests to be able to use JavaScript-like hashmap literals.我想在我的单元测试中使用 extern crate maplit以便能够使用类似 JavaScript 的 hashmap 文字。 I don't want to use maplit in my library code.我不想在我的库代码中使用 maplit。

maplit provides a macro that apparently must be activated using #[macro_use]. maplit 提供了一个显然必须使用#[macro_use] 激活的宏。 The only way I've been able to get this all working is to place this at the top of lib.rs :我能够让这一切正常工作的唯一方法是将它放在lib.rs的顶部:

#[cfg(test)] #[macro_use] extern crate maplit;

// my crate-specific stuff

At this point I realized I don't know what exactly #[cfg(test)] does.此时我意识到我不知道#[cfg(test)] 到底是做什么的。 I'm using it in my tests.我在我的测试中使用它。 These are included with library code, as per the convention, like so:根据约定,这些包含在库代码中,如下所示:

// some library code

#[cfg(test)]
mod test {
  use super::*;
  // tests here
}

I had thought that the line #[cfg(test)] was marking what follows until the end of the file (or block?) as only applicable to the test configuration.我原以为 #[cfg(test)] 行将直到文件(或块?)结尾之前的内容标记为仅适用于测试配置。

If so, then putting this directive at the top of lib.rs seems like a problem.如果是这样,那么将这个指令放在lib.rs的顶部似乎是一个问题。 Won't my entire library be dropped when I compile a distribution?当我编译一个发行版时,我的整个库不会被删除吗?

I've tried to find documentation on what exactly #[cfg(test)] does, but to no avail.我试图找到关于 #[cfg(test)] 究竟做了什么的文档,但无济于事。

#[....]

The above is a Rust Attribute which is like an annotation in other languages.上面是一个Rust 属性,类似于其他语言的注解。 For example;例如; in Java we have @Annotation(....) for methods and classes.在 Java 中,我们有 @Annotation @Annotation(....)用于方法和类。 Unlike annotation the rust attribute can be an expression that follows the attribute syntax.与注释不同,rust 属性可以是遵循属性语法的表达式。

#[cfg(....)]

The above is a compiler configuration attribute.以上是编译器配置属性。 The cfg() is one of many built-in attributes . cfg()是许多内置属性之一。

#[cfg(test)]

The above tells the Rust compiler that the following code should only be compiled when the test configuration is active .上面告诉 Rust 编译器下面的代码应该只在test配置激活时编译。 You can have other configuration attributes like debug , windows or features.您可以拥有其他配置属性,例如debugwindows或 features。

#[cfg(test)] #[macro_use] extern crate maplit;

Is the same as是相同的

#[cfg(test)]
#[macro_use]
extern crate maplit;

Which tells the Rust compiler to only compile the next line if the test configuration is active, and the next line tells Rust to only use macros from the following crate.这告诉 Rust 编译器仅在test配置处于活动状态时编译下一行,下一行告诉 Rust 仅使用来自以下板条箱的

If so, then putting this directive at the top of lib.rs seems like a problem.如果是这样,那么将这个指令放在 lib.rs 的顶部似乎是一个问题。 Won't my entire library be dropped when I compile a distribution?当我编译一个发行版时,我的整个库不会被删除吗?

The #[cfg(...)] attribute only applies the compiler condition upon the thing it is attached to. #[cfg(...)]属性仅将编译器条件应用于它所附加的事物

When you place the attribute at the top of the file followed by a space.当您将属性放在文件顶部时,后跟一个空格。 The attribute is attached to the current module or crate.该属性附加到当前模块或板条箱。

As shown here from the documentation example, the crate_type is applied to the entire file:如文档示例中所示, crate_type应用于整个文件:

// General metadata applied to the enclosing module or crate.
#![crate_type = "lib"]

// A function marked as a unit test
#[test]
fn test_foo() {
    /* ... */
}

// A conditionally-compiled module
#[cfg(target_os = "linux")]
mod bar {
    /* ... */
}

// A lint attribute used to suppress a warning/error
#[allow(non_camel_case_types)]
type int8_t = i8;

// Inner attribute applies to the entire function.
fn some_unused_variables() {
  #![allow(unused_variables)]

  let x = ();
  let y = ();
  let z = ();
}

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

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