Packages and Crates
crate是一个二进制可执行文件或者一个binary。crate root是Rust编译器开始编译的那个源文件,而且会作为对应crate的root module。package是一或多个提供一组功能的crates。package本身包含一个Cargo.toml来描述如何build对应的crates。
当键入cargo new my-project这一指令的时候,cargo就会创建一个Cargo.toml文件,生成一个package。默认src/main.rs是crate root。如果src/lib.rs存在,则会默认要生成一个library crate并且以src/lib.rs为crate root。如果同时存在src/main.rs和src/lib.rs,那么就会有两个crates,一个binary,一个library。
mod front_of_house {//mod keyword定义了一个module mod hosting {//mod可以嵌套 fn add_to_waitlist() {} fn seat_at_table() {} } mod serving { fn take_order() {} fn serve_order() {} fn take_payment() {} } }
默认mod中的方法,变量,结构体定义外界看不到,如果需要让不在同个crate的其他crate可见,需要加pub关键字。当然,子孙crate能够看到父辈crate的变量方法等。
mod front_of_house {
pub mod hosting {//pub关键字
pub fn add_to_waitlist() {}
使用其他Crate中的元素
要调用其他Crate元素,需要知道这个元素的路径。路径有绝对路径-从crate(root crate)或一个crate的名字开始-也有相对路径-从self,super或者当前module的某个标识符开始。路径用::分割。
fn eat_at_restaurant() { // Absolute path crate::front_of_house::hosting::add_to_waitlist(); // Relative path front_of_house::hosting::add_to_waitlist(); }
使用use关键字,能够将其他crate中的元素链接到当前crate中。例如:
use self::front_of_house::hosting;
就能在之后直接调用hosting。一般要调用某个元素,比如函数add_to_waitlist,就use其所在的package而不是这个函数本身,这是一种惯例。
use std::fmt; use std::io; fn function1() -> fmt::Result { // --snip-- } fn function2() -> io::Result<()> { // --snip-- }
use语句中,可以用as给元素起个别名。如use std::io::Result as IoResult;
可以使用*(The Glob Operator)引入全部可见子元素,比如use std::collections::*;
可以使用花括号+嵌套路径来简化use语句,如:use std::{cmp::Ordering, io};
Re-exporting
为了确保调用我们代码的其他代码也能够像我们的代码一样使用这些use,可以用pub use重新导出这些元素。例如:
pub use crate::front_of_house::hosting;
这样使用当前crate的其他crate也可以用简单的方式访问hosting内的元素。
搭配之后,可以将子元素移到不同文件中,然后在lib.rs或父crate统一导出。
例如:
front_of_house.rs Re-exporting子模块
pub mod hosting;
src/front_of_house/hosting.rs: 子模块中实现具体逻辑
pub fn add_to_waitlist() {}
使用外部package
需要把外部crate的名称和兼容版本号加入到Cargo.toml里,如下:
Cargo.toml
[dependencies] rand = "0.5.5"
main.rs
use rand::Rng; fn main() { let secret_number = rand::thread_rng().gen_range(1, 101); }
std提供的标准crate不需要修改Cargo.toml,但是需要用use引入。
use std::collections::HashMap;