先搞懂Rust中的项目管理——Crate、bin crate、lib crate、workspace
在Rust中想要完成一个稍微大一点的项目是不容易的,从JavaScript的角度来讲,不同js文件直接的互相导入是非常宽松且容易的,例如import、export等,甚至可以直接导出已经实例化的成员变量,但据我目前所知,在rust中暂时是不行的,rust只能导出一些类型和函数。
因此需要了解Rust中的项目管理、依赖。
1. crate、binary crate、library crate
先介绍几个概念:(粗体为原文,其余为我的理解)
- crate:一个模块(Module)的树形结构,它形成了库或二进制项目。 我一般不喜欢对专有名词进行翻译,如果硬要翻译,我愿称之为分隔箱,我觉得这个比喻很恰当。
- package:Cargo 的一个功能,它允许你构建、测试和分享 crate。包(package) 是提供一系列功能的一个或者多个 crate。一个包会包含有一个
Cargo.toml
文件,阐述如何去构建这些 crate。 - Module 和 use: 模块和
use
关键字允许你控制作用域和路径的私有性。 - 总体来说这三者的关系是
package > crate > module
。
binary crate
一个二进制crate,它的充分必要条件是会有./src/main.rs
这个文件,是整个用于执行crate的入口文件。
library crate
一个library crate,在某些翻译中也称为库crate或库,明显是翻译问题,及不准确。library crate的充分必要条件是有./src/lib.rs
这个文件。
规则
对于一个package来说,要满足以下的条件:
- 一个package最多包含一个library crate。
- 一个package可以包含任意多的binary crate。
- 一个package至少要包含一个crate(无论是binary或是library)。
回忆一下,如何新建一个项目,我会使用cargo new <pkg name>
命令,这个命令会在当前目录下自动创建一个binary application,因为会自动生成./src/main.rs
。
假设我们执行cargo new my-project
。
在此,我们有了一个只包含 src/main.rs
的包,意味着它只含有一个名为 my-project 的binary crate。如果一个包同时含有 src/main.rs
和 src/lib.rs
,则它有两个 crate:一个binary和一个library的,且名字都与包相同。
除此之外,可以通过将文件放在 src/bin
目录下,一个包可以拥有多个binary crate:每个 src/bin
下的文件都会被编译成一个独立的binary crate。
详细信息见该链接:https://kaisery.github.io/trpl-zh-cn/ch07-01-packages-and-crates.html。
如何处理一个library crate
在我之前学习的http-server项目中,http crate的目录结构是这样的:
可以看出这是一个library crate,在编写httprequest和httpresponse文件的代码时,我发现没有代码提示,后来我才知道,对于这种项目,在lib.rs中通过以下代码可以直接声明其他rs文件中的内容是一个mod:
pub mod httprequest;
pub mod httpresponse;
这也是lib.rs文件中唯一的两行代码,只要先在lib.rs中声明这两行代码,编译器就会任务这两个文件是个根目录形成树形结构的,这时就有代码提示了。
更详细的内容见该链接:https://www.tutorialspoint.com/rust/rust_modules.htm。
如何在没有package的情况下编译一个rs文件为library并为其他文件使用
假设现在目录下只有一个rary.rs文件,使用以下命令编译该文件:
// rary.rs
pub fn public_function() {println!("called rary's `public_function()`");
}fn private_function() {println!("called rary's `private_function()`");
}pub fn indirect_access() {print!("called rary's `indirect_access()`, that\n> ");private_function();
}
rustc --crate-type=lib rary.rs
就会生成一个library.rilb
文件,然后创建一个main.rs文件
// extern crate rary; // May be required for Rust 2015 edition or earlier 在2015版本之前需要这句话fn main() {rary::public_function();// Error! `private_function` is private//rary::private_function();rary::indirect_access();
}
然后用以下命令编译:
rustc main.rs --extern rary=library.rlib --edition=2018
就可以生成 main.exe 文件,然后通过./main
来执行main.exe这个文件。
详细内容见该链接https://doc.rust-lang.org/rust-by-example/crates/lib.html。
2. 工作空间 workspace
在之前的工作前构建了一个包含bin crate 和lib crate 的包。你可能会发现,随着项目开发的深入,lib crate 持续增大,而你希望将其进一步拆分成多个lib crate。对于这种情况,Cargo 提供了一个叫 工作空间(workspaces)的功能,它可以帮助我们管理多个相关的协同开发的pkg。
有了workspace之后,关系是这样的:
workspace > pkg > crate > mod
先创建一个文件夹作为工作空间,然后创建Cargo.toml作为配置文件:
[workspace]
members = ["tcpserver", "tcpclient", "httpserver", "http"]
这四个成员分别作为4个pkg,前两者是测试tcp连接的,后两者是构造http服务器的源文件,这4个包公用一个Cargo.lock。
运行时可以使用命令 cargo run -p <pkg name>
来运行指定的pkg。cargo test同理。
在同一个workspace下,如何在bin crate中引用lib crate
还是刚才的例子,http是一个lib crate,现在创建了一个bin crate名为httpserver。在Cargo.toml的[dependencies]中要表明http crate,即使这个crate是自己写的。
[package]
name = "httpserver"
version = "0.1.0"
edition = "2018"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
http = {path = "../http"}
serde = {version="1.0.136", features=["derive"]}
serde_json = "1.0.79"
详细内容见该链接https://kaisery.github.io/trpl-zh-cn/ch14-03-cargo-workspaces.html。
先搞懂Rust中的项目管理——Crate、bin crate、lib crate、workspace相关推荐
- 彻底搞懂 JS 中 this 机制
彻底搞懂 JS 中 this 机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 目录 this 是什么 this 的四种绑定规 ...
- 15个示例让你搞懂Linux中的cd命令
15个示例让你搞懂Linux中的cd命令 在Linux中,cd(更改目录)命令是新手和系统管理员最重要且使用最广泛的命令之一.对于没有头绪的管理员来说,cd是导航到其他目录以检查日志,执行程序/应用程 ...
- java 自旋锁_搞懂Java中的自旋锁
轻松搞懂Java中的自旋锁 前言 在之前的文章<一文彻底搞懂面试中常问的各种"锁">中介绍了Java中的各种"锁",可能对于不是很了解这些概念的同学 ...
- 分分搞懂c#中的委托
分分搞懂c#中的委托: 不说废话,不来虚的概念,不管代码是否有意义,看我的优化之路,你会理解委托了: 源代码1 public class test{//我们不管代码是否有意义,我们直接看代码重构和一步 ...
- 一文搞懂Qt中的颜色渐变(QGradient Class)
一文搞懂Qt中的颜色渐变(QGradient Class) 1, 快速开始! Qt中与颜色渐变有关的类是QGradient 其中它又有三个子类:QLinearGradient.QRadialGradi ...
- 帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
帮你彻底搞懂JS中的prototype.__proto__与constructor(图解) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文 ...
- 这一篇彻底搞懂JS中的prototype、__proto__与constructor真的很好
文章目录 1. 前言 2. _ _ proto _ _ 属性 3. prototype属性 4. constructor属性 5. 总结 提示:不要排斥,静下心来,认真读完,你就搞懂了!(可以先看一下 ...
- (转)帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
文章目录 1. 前言 2. _ _ proto _ _ 属性 3. prototype属性 4. constructor属性 5. 总结 提示:不要排斥,静下心来,认真读完,你就搞懂了!(可以先看一下 ...
- 彻底搞懂javascript中的replace函数
javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...
- 一文搞懂产品中的搜索设计
搜索功能是我们日常生活中接触最多的功能之一,它更够很好的提高用户使用产品的效率,用户对搜索功能的依赖性也比较大,所以设计好搜索功能将会很大程度上提高用户体验.本文作者通过分享这篇文章,帮我们搞懂产品中 ...
最新文章
- SpringBoot第十五篇:Springboot整合RabbitMQ
- 【干货】南京大学《模式识别》PPT
- c/c++十七: 变长参数
- html的学习小结(3):HTML 4.0 事件属性
- html怎样添加css样式,html添加css样式的方法
- Angular的工作原理
- 《深度学习笔记》——初识PyTorch的学习笔记
- python找到二维数据矩阵中的最大最小值直接使用min、max函数
- 用c语言把蜂鸣器封装成函数,C语言蜂鸣器问题
- 人工智能语音实训平台实验指导书
- JS纯前端实现文件保存
- mysql 3306无法访问_Mysql 3306端口无法被远程机器访问
- 山东省第八届 ACM 省赛 Parity check (规律、水)
- throw 和 throws 的区别
- TCP数据粘包的处理
- HALCON day1 C# 打开相机
- mysql 查询倒数第几
- AtCoder Beginner Contest 174 C.Repsept
- 【调剂】985北京航空航天大学软件学院调剂信息
- 机电传动控制 PLC梯形图编程练习
热门文章
- HOJ 12814 SIRO Challenge (状态压缩DP)
- html5 立方体 鼠标滑动,,HTML5超酷3D立方体按钮效果
- P2P追债也用上大数据
- 服务器虚拟化的工作原理,虚拟化技术及其原理
- 背包问题(Knapsack Problem)—— 0/1 背包问题 —— 总价值最大问题
- 并发编程之CompletableFuture全网最细最全用法(一)
- 英语单词在计算机中怎么存放,电脑怎么学英语单词
- Citrix PVS无盘系统最小环境搭建
- 常见bugger集合
- 分门别类刷leetcode——递归和回溯搜索(C++实现)