Rust选择编译时特性的能力可以提高代码的性能、大小、可维护性、安全性和可移植性。
下面是一些关于为什么在依赖项时应该主动使用编译时特性,并将这些特性提供给其他库用户。
在Rust中使用特性标志可以提高结果代码的性能,通过只包含特定应用程序所需的代码,可以避免因使用不必要的代码所带来的开销。
尽管有编译器优化来删除死代码,但这仍然可以产生更快、更高效的程序(并使编译器的工作更轻松)。
生成的二进制文件的总体大小受到包含的依赖项以及如何使用它们的影响。特性选择可以帮助生成的二进制文件更小,有利于需要分布或部署到资源受限环境的应用程序。
在等待上游库更新的过程中,我删除了本地项目的功能,该项目再次构建正常。这意味着您可以通过允许开发人员有选择地包含或排除特定功能来提高Rust代码的可维护性。
从统计学上讲,依赖的代码越多,出现安全问题的几率就越高。仅依赖于你所需要的功能来降低安全问题的几率是基于设计的安全思维,而“分块”提供自身的库有助于实现这一点。
还有一些方法可以根据你对实现的安全性的满意程度来选择相同功能的不同实现。例如,你可能更喜欢Rust原生TLS实现,而不是基于c的TLS实现,因为Rust是一种安全的语言,而且一些像Reqwest这样的库也提供了TLS后端选择。
[dependencies]
my-crate = { default-features = false, features = ["my-feature"] }
1#[cfg(feature = "my-feature")]
2fn my_function() {
3 // Code that is only included when the "my-feature" flag is enabled
4}
1#[cfg(feature = "my-feature")]
2mod my_module {
3 // Code that is only included when the "my-feature" flag is enabled
4}
1#[cfg_attr(feature = "my-feature", derive(Debug, PartialEq))]
2struct MyStruct {
3 // Fields and methods that are only included when the "my-feature" flag is enabled
4}
1#[cfg(target_os = "linux")]
2mod linux_specific_code {
3 // Linux-specific code goes here...
4}
1#[cfg(feature = "special_case")]
2impl MyTrait for MyType {
3 // Implementation of trait for special case goes here...
4}
1#[cfg(feature = "expensive_tests")]
2#[test]
3fn test_expensive_computation() {
4 // Test that performs expensive computation goes here...
5}
1#[cfg(feature = "long_benchmarks")]
2#[bench]
3fn bench_long_running_operation(b: &mut Bencher) {
4 // Benchmark for a long-running operation goes here...
5}
1#[cfg(all(feature = "my_feature1", feature = "my_feature2"))]
2fn my_function() {
3 // code for my_function
4}
要只在设置多个标志之一时启用一个特性,可以使用#[cfg(any(feature1, feature2,…))]属性。例如,当设置my_feature1或my_feature2标志时启用my_function():
1#[cfg(any(feature = "my_feature1", feature = "my_feature2"))]
2fn my_function() {
3 // code for my_function
4}
1//! Signal monitor
2#[cfg(unix)]
3#[path = "unix.rs"]
4mod imp;
5#[cfg(windows)]
6#[path = "windows.rs"]
7mod imp;
8#[cfg(not(any(windows, unix)))]
9#[path = "other.rs"]
10mod imp;
11pub use self::imp::create_signal_monitor;
1//! Memory allocator
2#[cfg(feature = "jemalloc")]
3#[global_allocator]
4static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
5#[cfg(feature = "tcmalloc")]
6#[global_allocator]
7static ALLOC: tcmalloc::TCMalloc = tcmalloc::TCMalloc;
8#[cfg(feature = "mimalloc")]
9#[global_allocator]
10static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
11#[cfg(feature = "snmalloc")]
12#[global_allocator]
13static ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc;
14#[cfg(feature = "rpmalloc")]
15#[global_allocator]
16static ALLOC: rpmalloc::RpMalloc = rpmalloc::RpMalloc
1//! Service launchers
2pub mod genkey;
3#[cfg(feature = "local")]
4pub mod local;
5#[cfg(feature = "manager")]
6pub mod manager;
7#[cfg(feature = "server")]
8pub mod server;