Structs(结构体)

  1. struct User {
  2. username: String,
  3. email: String,
  4. sign_in_count: u64,
  5. active: bool,
  6. }
  7. let mut user1 = User {
  8. email: String::from("someone@example.com"),
  9. username: String::from("someusername123"),
  10. active: true,
  11. sign_in_count: 1,
  12. };
  13. user1.email = String::from("anotheremail@example.com");
  14. // 结构体初始化缩写形式
  15. fn build_user(email: String, username: String) -> User {
  16. User {
  17. email, // email: email,
  18. username, // username: username,
  19. active: true,
  20. sign_in_count: 1,
  21. }
  22. }
  23. // 结构体更新语法
  24. let user2 = User {
  25. email: String::from("another@example.com"),
  26. username: String::from("anotherusername567"),
  27. ..user1 // active: user1.active, ...
  28. };

Tuple Structs(元组结构体)

  1. struct Color(i32, i32, i32);
  2. struct Point(i32, i32, i32);
  3. let black = Color(0, 0, 0);
  4. let origin = Point(0, 0, 0);
  • 元组结构体实质上是整体有名字但是成员没有名字的元组。
  • 成员完全相同但是结构体名字不同的两个元组结构体不是同一个类型。

    比如 Color 和 Point 是两个类型。
  • 可以定义完全没有成员的元组结构体:类单元结构体。

Debug 特质

自定义的结构体需要添加 Debug 特质才能正常输出。

  1. #[derive(Debug)]
  2. struct Rectangle {
  3. width: u32,
  4. height: u32,
  5. }
  6. fn main() {
  7. let rect1 = Rectangle { width: 30, height: 50 };
  8. println!("rect1 is {:?}", &rect1);
  9. println!("rect1 is {:#?}", &rect1);
  10. }
  11. /*
  12. rect1 is Rectangle { width: 30, height: 50 }
  13. rect1 is Rectangle {
  14. width: 30,
  15. height: 50
  16. }
  17. */

方法

  1. #[derive(Debug)]
  2. struct Rectangle {
  3. width: u32,
  4. height: u32,
  5. }
  6. impl Rectangle {
  7. fn area(&self) -> u32 {
  8. self.width * self.height
  9. }
  10. fn can_hold(&self, other: &Rectangle) -> bool {
  11. self.width > other.width && self.height > other.height
  12. }
  13. }
  14. impl Rectangle {
  15. fn square(size: u32) -> Rectangle {
  16. Rectangle { width: size, height: size }
  17. }
  18. }
  19. fn main() {
  20. let rect1 = Rectangle { width: 30, height: 50 };
  21. println!(
  22. "The area of the rectangle is {} square pixels.",
  23. rect1.area()
  24. );
  25. let rect2 = Rectangle { width: 10, height: 40 };
  26. let rect3 = Rectangle { width: 60, height: 45 };
  27. println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
  28. println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
  29. let sq = Rectangle::square(3);
  30. }
  31. /*
  32. The area of the rectangle is 1500 square pixels.
  33. Can rect1 hold rect2? true
  34. Can rect1 hold rect3? false
  35. */
  • 定义方法采用 impl 关键字。方法在结构体之外的 impl 块中定义。
  • 方法签名中指向结构体自身的参数有3种形式:self, &self, &mut self。
  • self 参数不需要标注类型。
  • 调用方法采用 object.method() 语法。

    object 形式固定,不受 self 参数形式的影响。
  • 同一个结构体的方法可以定义在多个 impl 块中。
  • impl 块中可以定义不带 self 参数的函数。这些函数通常用作构造器。

Enums(枚举)

  1. enum Message {
  2. Quit,
  3. Move { x: i32, y: i32 },
  4. Write(String),
  5. ChangeColor(i32, i32, i32),
  6. }
  7. impl Message {
  8. fn call(&self) {
  9. // method body would be defined here
  10. }
  11. }
  12. let m = Message::Write(String::from("hello"));
  13. m.call();

枚举是一种变体类型。

Option<T>

语言中没有空指针或 Null 引用,采用Option<T>类型。

  1. // 标准库中的 Option 类型
  2. enum Option<T> {
  3. Some(T),
  4. None,
  5. }
  1. let some_number = Some(5);
  2. let some_string = Some("a string");
  3. // None 的类型无法推导,需要标注
  4. let absent_number: Option<i32> = None;

match 表达式

  1. enum UsState {
  2. Alabama,
  3. Alaska,
  4. // --snip--
  5. }
  6. enum Coin {
  7. Penny,
  8. Nickel,
  9. Dime,
  10. Quarter(UsState),
  11. }
  12. fn value_in_cents(coin: Coin) -> u32 {
  13. match coin {
  14. Coin::Penny => 1,
  15. Coin::Nickel => 5,
  16. Coin::Dime => 10,
  17. Coin::Quarter(state) => {
  18. println!("State quarter from {:?}!", state);
  19. 25
  20. },
  21. }
  22. }
  23. value_in_cents(Coin::Quarter(UsState::Alaska)); // State quarter from Alaska!
  • match 表达式用来实现模式匹配。

    模式匹配语法:pattern => code,
  • 模式匹配必须穷尽所有可能。(exhaustive)
  • 存在相当于 else 的_模式。
  1. fn plus_one(x: Option<i32>) -> Option<i32> {
  2. match x {
  3. None => None,
  4. Some(i) => Some(i + 1),
  5. }
  6. }
  7. let five = Some(5);
  8. let six = plus_one(five);
  9. let none = plus_one(None);
  1. let some_u8_value = 0u8;
  2. match some_u8_value {
  3. 1 => println!("one"),
  4. 3 => println!("three"),
  5. 5 => println!("five"),
  6. 7 => println!("seven"),
  7. _ => (),
  8. }

if let

  1. let some_u8_value = Some(0u8);
  2. match some_u8_value {
  3. Some(3) => println!("three"),
  4. _ => (),
  5. }
  6. // 相当于
  7. if let Some(3) = some_u8_value {
  8. println!("three");
  9. }
  1. let mut count = 0;
  2. match coin {
  3. Coin::Quarter(state) => println!("State quarter from {:?}!", state),
  4. _ => count += 1,
  5. }
  6. // 相当于
  7. let mut count = 0;
  8. if let Coin::Quarter(state) = coin {
  9. println!("State quarter from {:?}!", state);
  10. } else {
  11. count += 1;
  12. }

Vec<T>

Vec<T> 是一种动态数组类型。

  1. // 空
  2. let v: Vec<i32> = Vec::new();
  3. // 带初值
  4. let v = vec![1, 2, 3];
  5. // 更新
  6. let mut v = Vec::new();
  7. v.push(5);
  8. v.push(6);
  9. v.push(7);
  10. v.push(8);
  11. // 取元素的两种方法
  12. let v = vec![1, 2, 3, 4, 5];
  13. let third: &i32 = &v[2];
  14. let third: Option<&i32> = v.get(2);
  15. // 数组越界
  16. let does_not_exist = &v[100]; // panic!
  17. let does_not_exist = v.get(100); // None
  18. // 遍历
  19. let v = vec![100, 32, 57];
  20. for i in &v {
  21. println!("{}", i);
  22. }
  23. let mut v = vec![100, 32, 57];
  24. for i in &mut v {
  25. *i += 50;
  26. }
  27. // 枚举类型(变体)的数组
  28. enum SpreadsheetCell {
  29. Int(i32),
  30. Float(f64),
  31. Text(String),
  32. }
  33. let row = vec![
  34. SpreadsheetCell::Int(3),
  35. SpreadsheetCell::Text(String::from("blue")),
  36. SpreadsheetCell::Float(10.12),
  37. ];

String 类型

  • String 和 str 都是 utf8 字符组成的数组类型。
  • str 类型没有所有权,不可变。
  • String 类型有所有权,可变。
  1. let mut s = String::new();
  2. // to_string 方法
  3. let data = "initial contents";
  4. let s = data.to_string();
  5. // the method also works on a literal directly:
  6. let s = "initial contents".to_string();
  7. // from 方法
  8. let hello = String::from("你好");
  9. // push_str 和 push 方法
  10. let mut s = String::from("foo");
  11. s.push_str("bar");
  12. s.push('l');
  13. // 字符串相加
  14. let s1 = String::from("Hello, ");
  15. let s2 = String::from("world!");
  16. let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
  17. // fn add(self, s: &str) -> String
  18. let s1 = String::from("tic");
  19. let s2 = String::from("tac");
  20. let s3 = String::from("toe");
  21. let s = s1 + "-" + &s2 + "-" + &s3;
  22. // 改用 format
  23. let s = format!("{}-{}-{}", s1, s2, s3);
  24. //
  25. let hello = "Здравствуйте";
  26. let len = hello.len(); // 24
  27. let s = &hello[0..4]; // Зд
  28. println!("{}, {}", len, s);
  29. for c in hello.chars() {
  30. print!("{} ", c); // З д р а в с т в у й т е
  31. }

HashMap 类型

  1. use std::collections::HashMap;
  2. // 使用 Vec 创建 HashMap
  3. let teams = vec![String::from("Blue"), String::from("Yellow")];
  4. let initial_scores = vec![10, 50];
  5. let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();
  6. // 创建并插入键值对
  7. let mut scores = HashMap::new();
  8. scores.insert(String::from("Blue"), 10);
  9. scores.insert(String::from("Yellow"), 50);
  10. let team_name = String::from("Blue");
  11. let score = scores.get(&team_name);
  12. for (key, value) in &scores {
  13. println!("{}: {}", key, value);
  14. }
  15. // 键不存在时插入,键存在时更新
  16. scores.insert(String::from("Blue"), 25);
  17. // 键不存在时插入
  18. scores.entry(String::from("Yellow")).or_insert(50);
  19. scores.entry(String::from("Blue")).or_insert(50);
  20. // 键不存在时插入,然后更新该值
  21. let text = "hello world wonderful world";
  22. let mut map = HashMap::new();
  23. for word in text.split_whitespace() {
  24. let count = map.entry(word).or_insert(0);
  25. *count += 1;
  26. }
  27. println!("{:?}", map);
  • HashMap 的键值对类型为 Copy 特质类型时,使用 Copy 语义。
  • HashMap 的键值对类型为非 Copy 特质类型(比如 String)时,使用 Move 语义。

Rust语言学习笔记(5)的更多相关文章

  1. Rust语言学习笔记(7)

    模块 // 兄弟模块 mod network { fn connect() { } } mod client { fn connect() { } } // 父子模块 mod network { fn ...

  2. Rust语言学习笔记(6)

    Traits(特质) // 特质 pub trait Summary { fn summarize(&self) -> String; } pub struct NewsArticle ...

  3. Rust语言学习笔记(4)

    Variables and Mutability(变量和可变性) 变量声明有三种:不变量(运行期的常量),变量以及(编译期的)常量. 变量可以重复绑定,后声明的变量覆盖前面声明的同名变量,重复绑定时可 ...

  4. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  5. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  6. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

  7. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  8. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  9. Go语言学习笔记十三: Map集合

    Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...

随机推荐

  1. SSH框架总结(环境搭建+框架分析+实例源码下载)

    一.SSH框架简介 SSH是struts+spring+hibernate集成的web应用程序开源框架. Struts:用来控制的,核心控制器是Controller. Spring:对Struts和H ...

  2. Entity Framework执行原生SQL语句

    ExecuteSqlCommand为执行命令的接口, SqlQuery 为返回查询结果 1.Database.ExecuteSqlCommand 方法 (String, Object[]) 对数据库执 ...

  3. vs code编辑器使用教程指南

    1.安装插件: 这里可以搜索到插件并安装. 2.修改快捷键或查找快捷键: 这里可以进行快捷键的查找和修改 3.进入引用文件: 点击f12,或者右击快捷键可以看到进入引用文件的快捷方法. 4.查看目录:

  4. OpenGL中移动单位中的‘单位’指什么

    opengl 比如 用到glm::translate(x,y,z) 表示 移动x,y,z个单位, 那么这个这个单位是指什么呢?这里的单位不是指像素,是根据投影矩阵的变化而变化的,默认情况下投影矩阵Pr ...

  5. Django的select_related 和 prefetch_related 函数优化查询

    在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子详解这两个函数的作用.虽然Q ...

  6. Vsftp的PASV mode(被动模式传送)和Port模式及 Linux下VsFTP配置全方案

    什么叫做PASV mode(被动模式传送)?他是如何工作的? FTP的连接一般是有两个连接的,一个是客户程和服务器传输命令的,另一个是数据传送的连接.FTP服务程序一般会支持两种不同的模式,一种是Po ...

  7. SP694 DISUBSTR - Distinct Substrings

    /* 统计每个节点的max和min, 然后求和即可 min = max[fa] + 1 */ #include<cstdio> #include<algorithm> #inc ...

  8. 了解Katalon的安装及基本使用(for mac)

    一.整体了解: 2018 top 6的自动化测试工具(网上了解): 1. Selenium 2. Katalon Studio 3. UFT 4. Watir 5. IBM Rational Func ...

  9. sql生成随机不重复字符串 可指定长度

    存储过程: create procedure dbo.GetRandStr () output) AS BEGIN ), ), @ss varchar DECLARE @I INTEGER, @cou ...

  10. day4----函数-闭包-装饰器

    本文档内容: 1 python中三种名称空间和作用域 2 函数的使用 3 闭包 4 装饰器 一 python中三种名称空间和作用域 1.1名称空间: 当程序运行时,代码从上至下依次执行,它会将变量与值 ...