昨天我們介紹了 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();
}
感謝大大補充 