你可能注意到null類型不在此列。他比較特殊貌笨,typeof對(duì)它的處理存在問(wèn)題:typeof null === "object"返回真,但是正確的結(jié)果應(yīng)該是"null"的,這個(gè)JavaScript內(nèi)部的bug由來(lái)已久——已經(jīng)存在了20多年心包,對(duì)于這個(gè)特性,因?yàn)闋砍兜教嗟膚eb系統(tǒng)缨恒,“修復(fù)”它會(huì)產(chǎn)生更過(guò)的bug谴咸,令太多的系統(tǒng)短時(shí)間內(nèi)無(wú)法工作。
結(jié)構(gòu)體是一個(gè)創(chuàng)建更復(fù)雜數(shù)據(jù)類型的方法骗露。普通結(jié)構(gòu)體的定義無(wú)需在末尾使用“岭佳;”,使用結(jié)構(gòu)體來(lái)定義一個(gè)變量應(yīng)該使用下面這樣的形式:結(jié)構(gòu)體名{字段名:值}萧锉,為字段賦值的順序不需要和聲明時(shí)保持一致珊随。結(jié)構(gòu)體變量可以使用.字段名來(lái)訪問(wèn)那個(gè)字段名所對(duì)應(yīng)的值。
fn main(){
let origin:Point = Point{x: 0, y: 0};
println!("{}", origin.x);//0
println!("{}", origin.y);//0
}
struct Point{
x: i32,
y: i32
}
1.結(jié)構(gòu)體不支持字段可變性
mut關(guān)鍵字是用來(lái)修飾借用以及綁定的柿隙。目前為止叶洞,rust在語(yǔ)言級(jí)別上還不支持字段可變性,所以如果你想像下面這樣寫(xiě)的話那么會(huì)報(bào)錯(cuò)禀崖。
struct Foo{
mut x: i32//語(yǔ)法錯(cuò)誤
}
盡管不支持字段可變性衩辟,但是rust可以通過(guò)其他詭異的方法來(lái)使得字段的值得到改變。如下所示:
fn main(){
let mut point:Point = Point{x: 1,y: 2};
point.x = 2;
println!("{}", point.x);
}
struct Point{
x: i32,
y: i32
}
上面的這個(gè)方法:我們明明是定義了一個(gè)可變的綁定波附,然而到最后我們卻能夠改變的結(jié)構(gòu)體變量的字段的值艺晴,要知道這之間是不存在什么邏輯之間的因果關(guān)系的,對(duì)于近乎完美的rust來(lái)說(shuō)這無(wú)疑是一點(diǎn)不足掸屡。而且要注意的是如果我們的的結(jié)構(gòu)體變量自身并不是一個(gè)可變的綁定的話封寞,那么修改字段的值將會(huì)報(bào)錯(cuò)。
盡管如此仅财,但是由于mut可以修飾借用狈究,所以結(jié)構(gòu)體中的字段的值也可以是一個(gè)可變的借用。這個(gè)時(shí)候可以達(dá)到間接修改字段的值的問(wèn)題盏求。如下所示:
fn main(){
let num:&mut i32 = &mut 9;
let foo:Foo = Foo{n: num};
*foo.n = 99;
println!("{}", *foo.n);//99
}
struct Foo<'a>{
n: &'a mut i32
}
2.更新語(yǔ)法
如果我們?cè)跇?gòu)造同一個(gè)結(jié)構(gòu)體的另一個(gè)對(duì)象的時(shí)候希望能夠利用這個(gè)結(jié)構(gòu)體先前所構(gòu)造出來(lái)的對(duì)象的某些字段抖锥,那么可以使用更新語(yǔ)法:在早前的結(jié)構(gòu)體變量前面加上..
下面可以看一個(gè)例子:
fn main(){
let point:Point = Point{x: 0, y: 1, z: 0};
let origin:Point = Point{y: 0, ..point};
println!("{} {} {}", origin.x, origin.y, origin.z);//0 0 0
}
struct Point{
x: i32,
y: i32,
z: i32
}
impl Point{
fn get_x(&self) -> i32{self.x}
fn get_y(&self) -> i32{self.y}
fn get_z(&self) -> i32{self.z}
}
需要注意的問(wèn)題亿眠,更新語(yǔ)法必須用在同一個(gè)類型的結(jié)構(gòu)體上,比如說(shuō)下面的這個(gè)例子就是錯(cuò)誤的:
//error[E0308]: mismatched types
fn main(){
let point:Point = Point{x: 1, y: 1, z: 1};
let color:RGB = RGB{x: 0, ..point}; //expected struct `RGB`, found struct `Point`
}
struct Point{
x: i32,
y: i32,
z: i32
}
impl Point{
fn get_x(&self) -> i32{self.x}
fn get_y(&self) -> i32{self.y}
fn get_z(&self) -> i32{self.z}
}
struct RGB{
x: i32,
y: i32,
z: i32
}
3.元組結(jié)構(gòu)體
Rust中有一個(gè)數(shù)據(jù)類型的表示方法很像元組和結(jié)構(gòu)體的混合體宁改,正由于這個(gè)特點(diǎn)我們叫他為元組結(jié)構(gòu)體缕探。元組結(jié)構(gòu)體的表示方法如下所示:struct 元組結(jié)構(gòu)體名();注意這里必須使用;對(duì)于普通的結(jié)構(gòu)體來(lái)說(shuō)我們并不需要使用 ;來(lái)結(jié)尾还蹲,但是對(duì)于元組結(jié)構(gòu)體來(lái)說(shuō)爹耗,我們必須使用;來(lái)結(jié)尾,而且對(duì)于元組結(jié)構(gòu)體來(lái)說(shuō)它不需要字段名谜喊,但是需要字段的數(shù)據(jù)類型潭兽。下面舉一個(gè)例子:
fn main(){
struct Color(i32, i32, i32);
let color:Color = Color(255, 255, 255);
println!("{} {} {}", color.0, color.1, color.2);//255 255 255
let Color(mut r, mut g, mut b) = color;
println!("{} {} {}", r, g, b);//255 255 255
r = 0;
println!("{} {}", r, color.0);//0 255
}
從 上面的例子我們可以看出:元組結(jié)構(gòu)體可以像元組一樣使用“.位置”來(lái)得到那個(gè)位置處的值,同時(shí)也可以let解構(gòu)來(lái)獲得每個(gè)項(xiàng)的值斗遏,同時(shí)利用let解構(gòu)的方法需要注意山卦。
4.類單元結(jié)構(gòu)體
類單元結(jié)構(gòu)體即是在結(jié)構(gòu)體中沒(méi)有使用任何字段。至于類單元結(jié)構(gòu)體有什么作用的話目前也還不清楚诵次。
fn main(){
struct EmptyStruct{};//定義類單元結(jié)構(gòu)體的方法一
struct EmptyStruct2;//定義類單元結(jié)構(gòu)體的方法二
let empty1 = EmptyStruct{};//必須使用{}
let empty2 = EmptyStruct2;//不需要使用{}
//Error: let empty3 = EmptyStruct;
}