一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Rust學(xué)習(xí)筆記(5)- 定義和實例化

 TestOps云層 2022-05-29 發(fā)布于上海

定義和實例化

結(jié)構(gòu)體和tuple類似,都可以將一些相關(guān)的值組織在一起,唯一不同的是結(jié)構(gòu)體里面的每一個變量需要命名,所以可讀性上比tuple更好,而且也不用關(guān)心里面的值的順序了。定義和賦值跟golang很像,直接用例子來看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}

fn main() {
let user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
}

然后學(xué)一種struct賦值的簡易形式,先看基本的:

1
2
3
4
5
6
7
8
fn build_user(email: String, username: String) -> User {
User {
email: email,
username: username,
active: true,
sign_in_count: 1,
}
}

email和username的參數(shù)名字和struct中的field的名字一致,那就可以簡寫:

1
2
3
4
5
6
7
8
fn build_user(email: String, username: String) -> User {
User {
email,
username,
active: true,
sign_in_count: 1,
}
}

用一個struct給另一個struct賦值

還是以上面那個struct為例,假設(shè)有一個user2,它的field中username、active、sign_in_count的值和user1一樣,只有email不一樣,那一般是這樣賦值:

1
2
3
4
5
6
7
8
9
10
fn main() {
// --snip--

let user2 = User {
active: user1.active,
username: user1.username,
email: String::from("another@example.com"),
sign_in_count: user1.sign_in_count,
};
}

不過Rust中有更方便的方式:

1
2
3
4
5
6
7
8
fn main() {
// --snip--

let user2 = User {
email: String::from("another@example.com"),
..user1
};
}

這寫法有點像ES6的語法,只不過ES6中是三個.,而Rust是一個.。不過需要注意,如果user1中有field發(fā)生“move”行為,那user1中那個field就失效了。就像上面這個例子,user1中的username,在賦值user2后,就失效了,后面不可以再訪問。

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

Rust允許定義類似tuple的struct,像這樣:

1
2
3
4
5
6
7
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}

這里的black和orgin雖然看似值一樣,但是不能互相賦值,因為類型不同。

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

就是沒有任何字段的結(jié)構(gòu)體:

1
2
3
4
5
struct AlwaysEqual;

fn main() {
let subject = AlwaysEqual;
}

關(guān)于struct的ownership

在struct中,一般不使用引用,因為Rust希望struct中的字段都能完整的擁有值,有統(tǒng)一的生命周期。如果要在其中使用引用,必須申明“生命周期”(lifetime),這個概念我們后面看。先看這個錯誤的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct User {
active: bool,
username: &str,
email: &str,
sign_in_count: u64,
}

fn main() {
let user1 = User {
email: "someone@example.com",
username: "someusername123",
active: true,
sign_in_count: 1,
};
}

將會報錯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ cargo run
Compiling structs v0.1.0 (file:///projects/structs)
error[E0106]: missing lifetime specifier
--> src/main.rs:3:15
|
3 | username: &str,
| ^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
1 ~ struct User<'a> {
2 | active: bool,
3 ~ username: &'a str,
|

error[E0106]: missing lifetime specifier
--> src/main.rs:4:12
|
4 | email: &str,
| ^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
1 ~ struct User<'a> {
2 | active: bool,
3 | username: &str,
4 ~ email: &'a str,
|

struct打印

struct默認(rèn)情況下不能直接用println進(jìn)行打印,看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct Rectangle {
width: u32,
height: u32,
}

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

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

這將會報錯:

1
error[E0277]: `Rectangle` doesn't implement `std::fmt::Display`

需要打開debug,才可以使用{:?}打印,或者{:#?}以更好看的形式打?。?/p>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}

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

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

打印效果是這樣的:

1
2
3
4
5
6
7
8
$ cargo run
Compiling rectangles v0.1.0 (file:///projects/rectangles)
Finished dev [unoptimized + debuginfo] target(s) in 0.48s
Running `target/debug/rectangles`
rect1 is Rectangle {
width: 30,
height: 50,
}

標(biāo)準(zhǔn)錯誤輸出

dbg!是標(biāo)準(zhǔn)錯誤輸出的宏,跟標(biāo)準(zhǔn)輸出println對應(yīng):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}

fn main() {
let scale = 2;
let rect1 = Rectangle {
width: dbg!(30 * scale),
height: 50,
};

dbg!(&rect1);
}

可以看到如下輸出:

1
2
3
4
5
6
7
8
9
$ cargo run
Compiling rectangles v0.1.0 (file:///projects/rectangles)
Finished dev [unoptimized + debuginfo] target(s) in 0.61s
Running `target/debug/rectangles`
[src/main.rs:10] 30 * scale = 60
[src/main.rs:14] &rect1 = Rectangle {
width: 60,
height: 50,
}

struct的方法

定義實現(xiàn)一個struct的方法,這個有點類似go語言,看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#[derive(Debug)]
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!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}

關(guān)鍵字impl表示實現(xiàn)后面的struct的方法,在里面所定義的所有方法,都從屬于這個struct。

area方法第一個參數(shù)是&self,表示這個struct的實例的引用,而在使用中,我們用rect1這個實例,調(diào)用area方法,這個實例就是代表了&self,所以area就不用這個參數(shù)了傳入了。

在C/C++中,其實還有一個->符號調(diào)用方法的語法,當(dāng)對象實例調(diào)用內(nèi)部方法,那就是用.,當(dāng)對象指針調(diào)用內(nèi)部方法,就是用->,不過Rust沒有這么麻煩,它會自行判斷,幫你添加.,&或者*,來匹配方法調(diào)用。所以下面兩種寫法其實是一回事,沒有區(qū)別:

1
2
p1.distance(&p2);
(&p1).distance(&p2);

關(guān)聯(lián)函數(shù)

關(guān)聯(lián)函數(shù)(Associated functions),其實就是java中的靜態(tài)函數(shù)的概念,在Rust中這樣定義:

1
2
3
4
5
6
7
8
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle {
width: size,
height: size,
}
}
}

這個在impl中的方法,沒有把&self作為參數(shù),這個方法稱為關(guān)聯(lián)函數(shù),它的調(diào)用方法是使用::,看下面的例子:

1
let sq = Rectangle::square(3);

Rust學(xué)習(xí)筆記(1)

Rust學(xué)習(xí)筆記(2)- Cargo包管理器

Rust學(xué)習(xí)筆記(3)- 變量和可變屬性

Rust學(xué)習(xí)筆記(4)-Ownership

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    99视频精品免费视频播放| 丰满人妻少妇精品一区二区三区| 精品亚洲一区二区三区w竹菊 | 久久精品亚洲精品一区| 色小姐干香蕉在线综合网| 精品女同一区二区三区| 国产高清一区二区不卡| 日韩国产亚洲一区二区三区| 国产精品一区二区不卡中文| 国产精品一区二区视频大全| 五月的丁香婷婷综合网| 精品推荐国产麻豆剧传媒| 国产超碰在线观看免费| 插进她的身体里在线观看骚| 国产精欧美一区二区三区久久| 五月激情综合在线视频| 国产在线一区中文字幕| 欧美日韩一级aa大片| 国产亚洲视频香蕉一区| 成在线人免费视频一区二区| 美日韩一区二区精品系列| 欧美午夜一区二区福利视频| 日本三区不卡高清更新二区| 欧美在线观看视频三区| 色欧美一区二区三区在线| 日本理论片午夜在线观看| 内射精品欧美一区二区三区久久久| 成人国产激情在线视频| 国产精品一区二区传媒蜜臀| 欧美日韩国产自拍亚洲| 日韩中文字幕狠狠人妻| 亚洲一区二区福利在线| 亚洲欧美日韩国产综合在线| 黄片免费播放一区二区| 日韩综合国产欧美一区| 日韩av生活片一区二区三区| 国产欧美日本在线播放| 国产欧美精品对白性色| 国产午夜福利不卡片在线观看| 亚洲另类欧美综合日韩精品 | 91偷拍裸体一区二区三区|