亚洲区国产区激情区无码区,国产成人mv视频在线观看,国产A毛片AAAAAA,亚洲精品国产首次亮相在线

Rust 結(jié)構(gòu)體

Rust 中的結(jié)構(gòu)體(Struct)與元組(Tuple)都可以將若干個(gè)類型不一定相同的數(shù)據(jù)捆綁在一起形成整體,但結(jié)構(gòu)體的每個(gè)成員和其本身都有一個(gè)名字,這樣訪問(wèn)它成員的時(shí)候就不用記住下標(biāo)了。元組常用于非定義的多值傳遞,而結(jié)構(gòu)體用于規(guī)范常用的數(shù)據(jù)結(jié)構(gòu)。結(jié)構(gòu)體的每個(gè)成員叫做"字段"。

結(jié)構(gòu)體定義

這是一個(gè)結(jié)構(gòu)體定義:

struct Site {
    domain: String,
    name: String,
    nation: String,
    found: u32
}

注意:如果你常用 C/C++,請(qǐng)記住在 Rust 里 struct 語(yǔ)句僅用來(lái)定義,不能聲明示例,結(jié)尾不需要 ; 符號(hào),而且每個(gè)字段定義之后用 , 分隔。

結(jié)構(gòu)體示例

Rust 很多地方受 JavaScript 影響,在示例化結(jié)構(gòu)體的時(shí)候用 JSON 對(duì)象的 key: value 語(yǔ)法來(lái)實(shí)現(xiàn)定義:

let nhooo = Site {
    domain: String::from("www.jixiangtaizi.com.cn"),
    name: String::from("nhooo"),
    nation: String::from("China"),
    found: 2013
};

如果你不了解 JSON 對(duì)象,你可以不用管它,記住格式就可以了:

結(jié)構(gòu)體類名 {
    字段名 : 字段值,
    ...
}

這樣的好處是不僅使程序更加直觀,還不需要按照定義的順序來(lái)輸入成員的值。

如果正在示例化的結(jié)構(gòu)體有字段名稱和現(xiàn)存變量名稱一樣的,可以簡(jiǎn)化書(shū)寫(xiě):

let domain = String::from("www.jixiangtaizi.com.cn");
let name = String::from("nhooo");
let nhooo = Site {
    domain,  // 等同于 domain : domain,
    name,    // 等同于 name : name,
    nation: String::from("China"),
    traffic: 2013
};

有這樣一種情況:你想要新建一個(gè)結(jié)構(gòu)體的示例,其中大部分屬性需要被設(shè)置成與現(xiàn)存的一個(gè)結(jié)構(gòu)體屬性一樣,僅需更改其中的一兩個(gè)字段的值,可以使用結(jié)構(gòu)體更新語(yǔ)法:

let site = Site {
    domain: String::from("www.jixiangtaizi.com.cn"),
    name: String::from("nhooo"),
    ..nhooo
};

注意:..nhooo 后面不可以有逗號(hào)。這種語(yǔ)法不允許一成不變的復(fù)制另一個(gè)結(jié)構(gòu)體示例,意思就是說(shuō)至少重新設(shè)定一個(gè)字段的值才能引用其他示例的值。

元組結(jié)構(gòu)體

有一種更簡(jiǎn)單的定義和使用結(jié)構(gòu)體的方式:元組結(jié)構(gòu)體

元組結(jié)構(gòu)體是一種形式是元組的結(jié)構(gòu)體。

與元組的區(qū)別是它有名字和固定的類型格式。它存在的意義是為了處理那些需要定義類型(經(jīng)常使用)又不想太復(fù)雜的簡(jiǎn)單數(shù)據(jù):

struct Color(u8, u8, u8);
struct Point(f64, f64);
let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);

"顏色"和"點(diǎn)坐標(biāo)"是常用的兩種數(shù)據(jù)類型,但如果示例化時(shí)寫(xiě)個(gè)大括號(hào)再寫(xiě)上兩個(gè)名字就為了可讀性犧牲了便捷性,Rust 不會(huì)遺留這個(gè)問(wèn)題。元組結(jié)構(gòu)體對(duì)象的使用方式和元組一樣,通過(guò) . 和下標(biāo)來(lái)進(jìn)行訪問(wèn):

fn main() {
    struct Color(u8, u8, u8);
    struct Point(f64, f64);

    let black = Color(0, 0, 0);
    let origin = Point(0.0, 0.0);

    println!("black = ({}, {}, {})", black.0, black.1, black.2);
    println!("origin = ({}, {})", origin.0, origin.1);
}

運(yùn)行結(jié)果:

black = (0, 0, 0)
origin = (0, 0)

結(jié)構(gòu)體所有權(quán)

結(jié)構(gòu)體必須掌握字段值所有權(quán),因?yàn)榻Y(jié)構(gòu)體失效的時(shí)候會(huì)釋放所有字段。

這就是為什么本章的案例中使用了 String 類型而不使用 &str 的原因。

但這不意味著結(jié)構(gòu)體中不定義引用型字段,這需要通過(guò)"生命周期"機(jī)制來(lái)實(shí)現(xiàn)。

但現(xiàn)在還難以說(shuō)明"生命周期"概念,所以只能在后面章節(jié)說(shuō)明。

輸出結(jié)構(gòu)體

調(diào)試中,完整地顯示出一個(gè)結(jié)構(gòu)體示例是非常有用的。但如果我們手動(dòng)的書(shū)寫(xiě)一個(gè)格式會(huì)非常的不方便。所以 Rust 提供了一個(gè)方便地輸出一整個(gè)結(jié)構(gòu)體的方法:

#[derive(Debug)]

struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };

    println!("rect1 is {:?}", rect1);
}

如第一行所示:一定要導(dǎo)入調(diào)試庫(kù) #[derive(Debug)] ,之后在 println 和 print 宏中就可以用 {:?} 占位符輸出一整個(gè)結(jié)構(gòu)體:

rect1 is Rectangle { width: 30, height: 50 }

如果屬性較多的話可以使用另一個(gè)占位符 {:#?} 。

輸出結(jié)果:

rect1 is Rectangle {
    width: 30,
    height: 50
}

結(jié)構(gòu)體方法

方法(Method)和函數(shù)(Function)類似,只不過(guò)它是用來(lái)操作結(jié)構(gòu)體示例的。

如果你學(xué)習(xí)過(guò)一些面向?qū)ο蟮恼Z(yǔ)言,那你一定很清楚函數(shù)一般放在類定義里并在函數(shù)中用 this 表示所操作的示例。

Rust 語(yǔ)言不是面向?qū)ο蟮?,從它所有?quán)機(jī)制的創(chuàng)新可以看出這一點(diǎn)。但是面向?qū)ο蟮恼滟F思想可以在 Rust 實(shí)現(xiàn)。

結(jié)構(gòu)體方法的第一個(gè)參數(shù)必須是 &self,不需聲明類型,因?yàn)?self 不是一種風(fēng)格而是關(guān)鍵字。

計(jì)算一個(gè)矩形的面積:

struct Rectangle {
    width: u32,
    height: u32,
}
    
impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    println!("rect1's area is {}", rect1.area());
}

輸出結(jié)果:

rect1's area is 1500

請(qǐng)注意,在調(diào)用結(jié)構(gòu)體方法的時(shí)候不需要填寫(xiě) self ,這是出于對(duì)使用方便性的考慮。

一個(gè)多參數(shù)的實(shí)例:

struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn wider(&self, rect: &Rectangle) -> bool {
        self.width > rect.width
    }
}

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    let rect2 = Rectangle { width: 40, height: 20 };

    println!("{}", rect1.wider(&rect2));
}

運(yùn)行結(jié)果:

false

這個(gè)程序計(jì)算 rect1 是否比 rect2 更寬。

結(jié)構(gòu)體關(guān)聯(lián)函數(shù)

之所以"結(jié)構(gòu)體方法"不叫"結(jié)構(gòu)體函數(shù)"是因?yàn)?quot;函數(shù)"這個(gè)名字留給了這種函數(shù):它在 impl 塊中卻沒(méi)有 &self 參數(shù)。

這種函數(shù)不依賴示例,但是使用它需要聲明是在哪個(gè) impl 塊中的。

一直使用的 String::from 函數(shù)就是一個(gè)"關(guān)聯(lián)函數(shù)"。

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn create(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }
}

fn main() {
    let rect = Rectangle::create(30, 50);
    println!("{:?}", rect);
}

運(yùn)行結(jié)果:

Rectangle { width: 30, height: 50 }

貼士:結(jié)構(gòu)體 impl 塊可以寫(xiě)幾次,效果相當(dāng)于它們內(nèi)容的拼接!

單元結(jié)構(gòu)體

結(jié)構(gòu)體可以只作為一種象征而無(wú)需任何成員:

struct UnitStruct;

我們稱這種沒(méi)有身體的結(jié)構(gòu)體為單元結(jié)構(gòu)體(Unit Struct)。