昨天我們介紹了 Module
今天會介紹引用的方式
如果我們要在其他地方使用 Module
裡面的東西
引用的方式會分為絕對路徑及相對路徑
以生活中的例子來說,絕對路徑就是準確的地址,全球獨一無二的地址
台北車站的地址為 中華民國(臺灣)臺北市中正區黎明里北平西路3號忠孝西路一段49號
在 Rust 中,要使用絕對路徑就必須完整地寫出位址
Module 應該是要統一放在一個檔案中,不過為了方便展示我先放在同一個檔案中
我們定義了一個 product 的 Module ,裡面有個叫做 Sugar 的結構(其實就是昨天的例子)
接著要在 sell_product 這個 Function 中,引用 product Module
我們使用絕對路徑來引用
在 product::Sugar
前面要加上 crate
為什麼是 crate
, crate
代表根目錄的意思,無論是這個 Module 是放在 src/main.rs
還是 src/lib.rs
, crate
會直接指向這兩個檔案
crate
的作用就像 /
一樣
fn main() {
sell_product();
}
mod product {
#[derive(Debug)]
pub struct Sugar {
pub name: String,
}
}
fn sell_product() {
let toffee = crate::product::Sugar {
name: "toffee".to_string(),
};
println!("{:?}", toffee)
}
> cargo run
Sugar { name: "toffee" }
我們向迷路的人解釋該怎麼到達目的地時,都是使用相對路徑的方式來解釋
相對路徑是要以引用的這個 Function 在哪裡為出發
用剛剛的例子來看,假設我們要改成相對路徑,其實只要把 crate
刪除就好了
主要是因為 sell_product
與 product
都在根目錄中,所以這樣用也可以引用到
fn main() {
sell_product();
}
mod product {
#[derive(Debug)]
pub struct Sugar {
pub name: String,
}
}
fn sell_product() {
let toffee = product::Sugar {
name: "toffee".to_string(),
};
println!("{:?}", toffee)
}
> cargo run
Sugar { name: "toffee" }
在相對路徑中,我們也可以用 super 來代表 上一層 Module
來看到 staff::responsibility
這邊,我們用 super
往上一層,並引用了 product
這個 Module
fn main() {
let amy = staff::person {
name: "amy".to_string(),
};
println!("{:?} is charge of {:?}", amy.name, staff::responsibility())
}
mod product {
#[derive(Debug)]
pub struct Sugar {
pub name: String,
}
}
mod staff {
#[derive(Debug)]
pub struct person {
pub name: String,
}
pub fn responsibility() -> String {
let charge = super::product::Sugar {
name: "coffee sugar".to_string(),
};
charge.name
}
}
> cargo run
"amy" is charge of "coffee sugar"
self 就是本身所在的地方
以下方例子來說,因為 staff module 一樣是放置在 crate 中
引用的話就可以用 self
fn main() {
let amy = self::staff::person {
name: "amy".to_string(),
};
println!("{:?} is charge of {:?}", amy.name, staff::responsibility())
}
mod product {
#[derive(Debug)]
pub struct Sugar {
pub name: String,
}
}
mod staff {
#[derive(Debug)]
pub struct person {
pub name: String,
}
pub fn responsibility() -> String {
let charge = super::product::Sugar {
name: "coffee sugar".to_string(),
};
charge.name
}
}
> cargo run
"amy" is charge of "coffee sugar"
通常會以絕對路徑為先,基本上定義 Module 的檔案比較少被挪動
引用的地方就不需要一直去修改
幫補一下:
大大的例子self是可以省略的,在同一個namespace裡不需特別寫,一般是省略不寫的:
那為什麼還要有self
呢,比較常用的場景是在use:
pub mod my {
pub fn hello() { println!("hello"); }
pub mod lib {
pub enum Ning { Hello }
pub fn hello() { println!("inner hello"); }
pub struct Yang { name: String, }
}
}
有時候在use時,要用時用該項目(lib)及其子項目(Ning),加個self
就可以不用寫兩行use
了:
use my::{hello, lib::{self, Ning}};
fn main() {
hello();
lib::hello();
}
感謝大大補充