iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0

昨天我們介紹了 Module

今天會介紹引用的方式

Module 路徑

如果我們要在其他地方使用 Module 裡面的東西

引用的方式會分為絕對路徑及相對路徑

絕對路徑

以生活中的例子來說,絕對路徑就是準確的地址,全球獨一無二的地址

台北車站的地址為 中華民國(臺灣)臺北市中正區黎明里北平西路3號忠孝西路一段49號

在 Rust 中,要使用絕對路徑就必須完整地寫出位址

Module 應該是要統一放在一個檔案中,不過為了方便展示我先放在同一個檔案中

我們定義了一個 product 的 Module ,裡面有個叫做 Sugar 的結構(其實就是昨天的例子)

接著要在 sell_product 這個 Function 中,引用 product Module

我們使用絕對路徑來引用

product::Sugar 前面要加上 crate

為什麼是 cratecrate 代表根目錄的意思,無論是這個 Module 是放在 src/main.rs 還是 src/lib.rscrate 會直接指向這兩個檔案

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_productproduct 都在根目錄中,所以這樣用也可以引用到

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

在相對路徑中,我們也可以用 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

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 的檔案比較少被挪動

引用的地方就不需要一直去修改


上一篇
Day 23 - Module part 1
下一篇
Day 25 - 泛型 part 1
系列文
成為程式界的 F1 賽車手,用 30 天認識 Rust 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
hello world
iT邦新手 5 級 ‧ 2023-10-09 16:57:40

幫補一下:

大大的例子self是可以省略的,在同一個namespace裡不需特別寫,一般是省略不寫的:

self可以省略

那為什麼還要有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();
}

感謝大大補充 /images/emoticon/emoticon12.gif

我要留言

立即登入留言