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

2018-08-12 22:03 更新

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

結(jié)構(gòu)體是創(chuàng)建更復(fù)雜的數(shù)據(jù)類型的一種方式。例如,如果我們做涉及在二維空間中的坐標(biāo)計(jì)算時(shí),我們可能既需要 x 的值,也需要 y 的值:

let origin_x = 0;
let origin_y = 0;

一個(gè)結(jié)構(gòu)體讓我們將二者結(jié)合成為一個(gè)單一的,統(tǒng)一的數(shù)據(jù)類型:

struct Point {
x: i32,
y: i32,
}

fn main() {
let origin = Point { x: 0, y: 0 }; // origin: Point

println!("The origin is at ({}, {})", origin.x, origin.y);
}

這里有許多東西需要講,所以先在這里打斷一下。我們用一個(gè) struct 關(guān)鍵字來(lái)聲明一個(gè)結(jié)構(gòu)體 ,同時(shí) struct 后跟著此結(jié)構(gòu)體的名字。按照慣例,結(jié)構(gòu)體以大寫(xiě)字母開(kāi)頭,同時(shí)都為駝峰式書(shū)寫(xiě):PointInSpace ,而不是Point_In_Space。

我們可以通過(guò) let 來(lái)創(chuàng)建一個(gè)我們的結(jié)構(gòu)體的實(shí)例,像往常一樣,但是我們使用一個(gè)關(guān)鍵字:值的語(yǔ)法風(fēng)格來(lái)設(shè)置每個(gè)字段。不要求順序與原始聲明的順序相同。

最后,因?yàn)樽侄涡枰Q,我們可以通過(guò)點(diǎn)符號(hào)來(lái)訪問(wèn)字段:origin.x。

在默認(rèn)情況下,結(jié)構(gòu)體中的值像 Rust 中的其他綁定一樣都是不可變的。我們使用 mut 關(guān)鍵字來(lái)使它們?yōu)榭勺儯?

struct Point {
x: i32,
y: i32,
}

fn main() {
let mut point = Point { x: 0, y: 0 };

point.x = 5;

println!("The point is at ({}, {})", point.x, point.y);
}

以上代碼將打印 The point is at (5, 0)。

Rust 在語(yǔ)言層面不支持字段可變性,所以你不能像以下這樣書(shū)寫(xiě)代碼:

struct Point {
mut x: i32,
y: i32,
}

可變性是綁定的一個(gè)屬性,而不是結(jié)構(gòu)體本身。如果你習(xí)慣于字段級(jí)別可變性,第一次用起來(lái)會(huì)感覺(jué)很奇怪,但是它極大的簡(jiǎn)化了一些東西。它甚至允許您使某東西為可變,但是僅僅適用于短時(shí)間內(nèi):

struct Point {
x: i32,
y: i32,
}

fn main() {
let mut point = Point { x: 0, y: 0 };

point.x = 5;

let point = point; // this new binding can’t change now

point.y = 6; // this causes an error
}

語(yǔ)法更新

一個(gè)結(jié)構(gòu)體可以包含 .. 來(lái)表明你想要使用一些其他結(jié)構(gòu)體的副本用于某些值。例如:

struct Point3d {
x: i32,
y: i32,
z: i32,
}

let mut point = Point3d { x: 0, y: 0, z: 0 };
point = Point3d { y: 1, .. point };

以上代碼中給了 point 結(jié)構(gòu)體一個(gè)新的 y,但是仍然保持 xz 的原來(lái)的值。它也并不一定是相同的結(jié)構(gòu)體,當(dāng)你想要添加新的變量時(shí)可以使用這個(gè)語(yǔ)法,同時(shí)它會(huì)復(fù)制你沒(méi)有指定的值:

let origin = Point3d { x: 0, y: 0, z: 0 };
let point = Point3d { z: 1, x: 2, .. origin };

數(shù)組結(jié)構(gòu)體

Rust 有另外一個(gè)數(shù)據(jù)類型就像一個(gè)數(shù)組與一個(gè)結(jié)構(gòu)體的混合,稱為“數(shù)組結(jié)構(gòu)體”。數(shù)組結(jié)構(gòu)體有一個(gè)名字,但是它們的字段沒(méi)有名字:

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

以上代碼中的兩個(gè)結(jié)構(gòu)體不相等,即使它們有相同的值:

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

與數(shù)組結(jié)構(gòu)體相比,使用結(jié)構(gòu)體幾乎總是比較好。我們可以像如下代碼一樣書(shū)寫(xiě) ColorPoint

struct Color {
red: i32,
blue: i32,
green: i32,
}

struct Point {
x: i32,
y: i32,
z: i32,
}

現(xiàn)在,我們有真正的名字,而不是位置。好名字固然重要,同時(shí),結(jié)構(gòu)體我們需要有真正的名字。

一種情況下,數(shù)組結(jié)構(gòu)體非常有用,盡管,那樣一個(gè)數(shù)組結(jié)構(gòu)體僅包含一個(gè)元素。我們稱之為‘新型’模式,因?yàn)樗试S我們創(chuàng)建一個(gè)新的類型,不同于其包含的值,并表示它自己的語(yǔ)義:

struct Inches(i32);

let length = Inches(10);

let Inches(integer_length) = length;
println!("length is {} inches", integer_length);

正如你所看到的,你可以通過(guò)一個(gè)非結(jié)構(gòu)化的 let 關(guān)鍵字來(lái)提取內(nèi)在的整數(shù)類型,正如通常的數(shù)組一樣。在這種情況下,let Inches(integer_length)10 賦值給 integer_length。

Unit-like 結(jié)構(gòu)體

你可以定義一個(gè)根本沒(méi)有任何成員的結(jié)構(gòu)體:

struct Electron;

這樣的結(jié)構(gòu)體被稱為 ‘unit-like’ ,因?yàn)樗愃朴诳諗?shù)組,(),有時(shí)被稱為 ‘unit’。與數(shù)組結(jié)構(gòu)體一樣,它定義了一個(gè)新的類型。

這種結(jié)構(gòu)體通常對(duì)自己沒(méi)有什么用處(雖然它有時(shí)可以作為一個(gè)標(biāo)記類型使用),但是結(jié)合其他的功能,它可以變的有用。例如,一個(gè)庫(kù)可能想要要求你創(chuàng)建一個(gè)可以實(shí)現(xiàn)某些特定特征的結(jié)構(gòu)體來(lái)處理事件。如果你沒(méi)有需要在結(jié)構(gòu)體中存儲(chǔ)的數(shù)據(jù),你可以只創(chuàng)建一個(gè) unit-like 結(jié)構(gòu)體。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)