最简单的例子讲解如何使用 feature
某一天,我有一个需求是使用Feature去控制一段代码逻辑,但是嘞,当时我只是在 引用第三方库的时候才见过 feature 这个东西,还是报错之后的代码提示用什么 feature ,,,所以只知道不同的 feature 会有不同的代码,除此之外就一问三不知了,不知道你是不是目前也是这样 哈哈
但是刚好有这个需求了,正好也可以深入了解一下,但比较坑的是,我在能找到的资料,虽然事后看起来全面且准确的对 feature 做了介绍,但是对于刚接触 feature 的人来说感觉就是 隔靴搔痒 ,总是有一层面纱覆盖在 feature 上面,让你一时无法快速的 看清楚 feature 是个啥。
但是在我花了点时间完全弄清楚这个之后,发现,啊就这? 这么简单?但是也同时也提出一个疑问,为什这么简单的东西,我看资料却总是弄不清楚呢? 看来大佬写的东西类似于教科书一类的东西,大而全,但是对初学者不太友好,所以嘞,在弄清楚如何使用 feature 之后,我打算用一个足够简单的例子去讲解 feature 如何使用
先说 feature 是干啥的
这是个啥呢?这是一种特性,可以让 cargo 有选择性的对你写的代码进行编译
例如下面有两行代码,非常简单的代码
println!("a");
println!("b");
使用 feature 就可以让其只编译 println!("a"); 或者 只编译 println!("b"); 或者都编译或者都不编译,随你所想,那这种选择编译有什么用呢?在这里你可以发挥你的想象,这种功能能做的事情好像有点多,我随便说几个吧
-
控制代码流程
例如想在某些情况下启动软件后只执行打印b的逻辑,而不执行打印a的逻辑,只需要不编译 println!("a"); 就可以实现
-
减少编译任务量
我们经常会遇到在使用第三方库的时候,他很大,导致编译的时间比较长,这时候就可以把自己用不到的 feature 给关掉,尽可能地去减少代码编译时间
-
隐藏不稳定代码
比如我们在编写代码的时候,经常会有还没有完成,但是正在编辑的功能,就可以 用一个 unstable 的 feature 去包含这些代码,这样在实际使用的时候,就不会用到这些代码。
-
实验性的代码生成或优化
在某些情况下,编译器团队可能会为 Rustc 提供实验性的优化或代码生成策略,而这些可以通过特性标志来启用
等等,完全可以围绕可以控制代码的编译这一特点发挥更多的应用场景,好了,用处说完了,下面讲解怎么实现,开干!
怎么用
继续拿上面的简单代码举例
声明 feature
首先要在Cargo.toml 文件里加入你的 feature
例如你想要一个 编译 打印 a 的 feature
和一个编译 打印 b 的 feature
, 在文件里添加以下内容
[features]
print-a = []
print-b = []
如果 想a b同时打印嘞,只需要再使用时将这两个 feature
都打开就可以了,有些同学可能见过有些第三方库使用 features = ["full"] 的情况,我们也可以这样做:
[features]
print-a = []
print-b = []
full = ["print-a","print-b"]
使用 feature
只需要把这两个添加到方括号里就可以了。 feature
声明好了,就可以去代码里进行使用了
#[cfg(feature="print-a")]
println!("a");
#[cfg(feature="print-b")]
println!("b");
在你想控制的代码上面直接添加#[cfg(.....)]
里面添加对应的feature
名称就可以了
这个时候代码你会发现变灰了,意思是cargo对你说这里面的代码我不管了,你随意,也不会进行检查,也不会对这两个代码进行编译。
默认 feature
如果在工作中默认只需要打印 a ,而不是什么都不做,这个时候呢就可以在toml文件里设置默认的 feature
[features]
default = ["print-a"]
print-a = []
print-b = []
full = ["print-a","print-b"]
回到代码部分就会发现
#[cfg(feature="print-a")]
println!("a");
print-a
的这两行代码已经重新变亮了,意味着默认会编译打印a的代码。
把代码跑起来
好了,下面代码写完了,就剩下如何让其跑起来了,也不复杂,超级简单,如果是运行默认实现,直接cargo r
就可以让其运行并看到一下输出结果
alain@DESKTOP-TPGMEK3:~/LearnRust$ cargo r
Compiling mytest v0.1.0 (/home/alain/LearnRust)
Finished dev [unoptimized + debuginfo] target(s) in 0.11s
Running `target/debug/mytest`
a
可以看到纸打印了一个a
想要同时开启feature
print-b
则输入cargo r -F print-b
会看到以下输出:
alain@DESKTOP-TPGMEK3:~/LearnRust$ cargo r -F print-b
Compiling mytest v0.1.0 (/home/alain/LearnRust)
Finished dev [unoptimized + debuginfo] target(s) in 0.10s
Running `target/debug/mytest`
a
b
可以使用cargo -h
查看更多快捷指令信息 可以看到-F就是--features的简写,除此之外还有其他控制feature的指令信息
-F, --features Space or comma separated list of features to activate
--all-features Activate all available features
--no-default-features Do not activate the `default` feature
比如
- 开启所有
features
使用--all-features
- 关闭默认
features
使用--no-default-features
使用第三方库时选择feature
工作中比较常见的就是在引用其他库的时候需要经常与 feature
打交道,想要开启库中的某些 feature
可以这样做
[dependencies]
# Enables the `derive` feature of serde.
serde = { version = "1.0.118", features = ["derive"] }
想要关闭某些 feature
可以这样做:
[dependencies]
flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] }
也可以在这里关闭默认 feature
[dependencies]
jpeg-decoder = { version = "0.1.20", default-features = false }
如何查看使用的库有哪些 feature
要查看一个 Rust 库的可用 features,您可以查看该库的 Cargo.toml
文件。在这个文件中,会有一个 [features]
部分,列出了所有的可选 features 和它们的依赖。
类似于我们上面写的,所有 features 会事先声明在这里。
[features]
print-a = []
print-b = []
full = ["print-a","print-b"]
将上面的知识装入你的脑子
好了,我相信你在看完这篇文章后,已定对 features 已经有了一个深入的了解 ,是的就是这么简单,最后将其装到你的脑袋里,恭喜,你已经学会了 features!
from刘金,转载请注明原文链接。感谢!