Rust:快速学会 如何使用 feature 控制代码逻辑

2023年 10月 12日 122.7k 0

最简单的例子讲解如何使用 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刘金,转载请注明原文链接。感谢!

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论