Что делает # [cfg (test)], когда находится в верхней части lib.rs? - PullRequest
3 голосов
/ 01 ноября 2019

Я пишу библиотеку Rust (сгенерированную из груза) с юнит-тестами.

Я бы хотел использовать внешний ящик maplit в своих юнит-тестах, чтобы иметь возможность использоватьJavaScript-подобные литералы hashmap. Я не хочу использовать maplit в коде моей библиотеки.

maplit предоставляет макрос, который, очевидно, должен быть активирован с помощью # [macro_use]. Единственный способ заставить все это работать - поместить это на вершину lib.rs:

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

// my crate-specific stuff

В этот момент я понял, что не знаю, что именно # [cfg (тест)] делает. Я использую это в своих тестах. Они включены в библиотечный код в соответствии с соглашением, например так:

// some library code

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

Я думал, что строка # [cfg (test)] маркирует то, что следует до конца файла (или блока)?) применимо только к тестовой конфигурации.

Если это так, то размещение этой директивы в верхней части lib.rs кажется проблемой. Не упадет ли вся моя библиотека при компиляции дистрибутива?

Я пытался найти документацию о том, что именно делает [[cfg (test)]), но безрезультатно.

1 Ответ

3 голосов
/ 01 ноября 2019
#[....]

Выше приведен атрибут Rust , похожий на аннотацию на других языках. Например;в Java у нас есть @Annotation(....) для методов и классов. В отличие от аннотации атрибут rust может быть выражением, которое соответствует синтаксису атрибута.

#[cfg(....)]

Выше приведен атрибут конфигурации компилятора . cfg() является одним из многих встроенных атрибутов .

#[cfg(test)]

Выше указано, что компилятор Rust должен компилировать следующий код, только когда test имеет конфигурацию активный . У вас могут быть другие атрибуты конфигурации, такие как debug, windows или функции.

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

То же, что

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

, который говорит компилятору Rust компилировать только следующую строкуесли конфигурация test активна, и следующая строка говорит Rust использовать только макросов из следующего ящика.

Если это так, то поместите эту директиву в верхнюю частьlib.rs кажется проблемой. Не будет ли отброшена вся моя библиотека при компиляции дистрибутива?

Атрибут #[cfg(...)] применяет условие компилятора только к объекту , к которому он присоединен.

При размещении атрибута в верхней части файла следует пробел. Атрибут прикреплен к текущему модулю или ящику.

Как показано здесь из примера документации, 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 = ();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...