use crate
Để sử dụng (import) một crate từ https://crates.io, ví dụ https://crates.io/crates/log.
1. Thêm crate vào Cargo.toml
Có 2 cách
Cách 1: Edit trực tiếp file Cargo.toml
[dependencies]
log = "0.4"
Cách 2: Sử dụng cargo add
, cargo sẽ tự động update file Cargo.toml
cho bạn
cargo add log
[dependencies]
log = "0.4.17"
Để thêm crate vào dev dependencies (dùng cho tests), ta thêm --dev
vào lệnh:
cargo add --dev log
[dev-dependencies]
log = "0.4.17"
2. Sử dụng crate trong code
fn main() { log::info!("hello"); log::error!("oops"); }
Sử dụng keyword use
. Chức năng chính của use
là bind lại full path
của element vào một tên mới, để chúng ta không cần phải lặp lại một tên dài mỗi lần sử dụng.
use log::info; use log::error; fn main() { info!("hello"); error!("oops"); }
Nhóm các import lại với nhau:
use log::{info, error}; fn main() { info!("hello"); error!("oops"); }
Import mọi thứ được public trong crate/module. Cách này thường hay tránh bởi
sẽ khó biết được function, struct, ... nào đó đang thuộc crate nào, ngoại trừ các prelude::*
.
use log::*; fn main() { info!("hello"); error!("oops"); }
use
trong scope
use
cũng thường được sử dụng import element vào trong scope hiện tại.
#![allow(unused)] fn main() { fn hello() -> String { "Hello, world!".to_string() } #[cfg(test)] mod tests { use super::hello; // Import the `hello()` function into the scope #[test] fn test_hello() { assert_eq!("Hello, world!", hello()); // If not using the above `use` statement, we can run same via `super::hello()` } } }
Bạn sẽ sẽ hay gặp:
#![allow(unused)] fn main() { // ... #[cfg(test)] mod tests { use super::*; use log::info; // ... } }
self::
, super::
Mặc định thì use
sẽ import đường dẫn tuyệt đối, bắt đầu từ crate root.
self
và super
thường dùng để import mod theo vị trí tương đối.
#![allow(unused)] fn main() { // src/level_1/level_2/mod.rs use self::hello_1; use super::super::level3::hello_2; }
Re-export
Một trường hợp đặt biệt là sử dụng pub use
là re-exporting,
khi bạn thiết kế một module bạn có thể export một số thứ từ module khác (*) từ module của bạn.
Do đó người sử dụng có thể sử dụng các module khác đó ngay từ module của bạn.
Module khác (*) đó có thể là một internal module, internal crate hoặc external crate.
#![allow(unused)] fn main() { // src/utils.rs pub use log::*; }
// src/main.rs use crate::utils::info; fn main() { info!("..."); }
Pattern này được sử dụng khá nhiều ở các thư viện lớn. Nó giúp ẩn đi các internal module phức tạp của library đối với user. Bởi vì user sẽ không cần quan tâm đến cấu trúc directory phức tạp khi sử dụng một library nào đó.