rust学习疑惑

1.字节字面量是什么?
2.数组元素默认不可变?
3.vec!宏是干嘛的 用来定义向量的
4.静态生命周期 是什么?
5.unsafe块
6.字节序列转切片然后再转str是在干嘛
7.panic宏
8.单元结构体
9.带参数枚举体
10.智能指针的好处
11.trait到底是个啥?啥是Debug trait

2语言精要

2.1 Rust语言的基本构成

Rust主要由以下几个核心部件构成:

  • 语言规范
  • 编译器
  • 核心库
  • 标准库
  • 包管理器

2.1.1语言规范

Rust语言规范主要由rust语言参考和RFC文档共同构成

Rust语言参考

包含三部分内容

  • 对每种语言结构及用法的描述
  • 对内存模型、并法模型、链接、调试等内存的描述
  • 影响语言设计的基本原理和描述

2.1.2 编译器即 rustc

2.1.3 核心库

可以通过在模块顶部插入#![no_std]来使用核心库。核心库和标准库功能有一些重复,包含以下部分:

  • 基础的trait,如Copy,Debug,Display,Option等
  • 基本的原始类型,如bool,char,i8/u8,i16/u16,i32/u32,i64/u64,isize/usize,f32/f64,str,array,slice,tuple,pointer等
  • 常用功能型数据类型,如String,Vec,HashMap,Rc,Arc,Box等
  • 常用的宏定义,如println!,assert!,panic!,vec!等

2.1.4 标准库

标准库包含的内容大概如下:

  • 与核心库一样的基本trait、原始数据类型、功能型数据类型和常用宏
  • 并法、I/O和运行时,例如线程模块、用于消息传递的消息通道、Sync trait等并法模块,文件、TCP、UDP、管道、套接字等。
  • 平台抽象,os相关
  • 底层操作接口,std::mem,std:ptr,std::intrinsics等
  • 可选和错误处理类型Option和Result

2.1.5 包管理器

2.2 语句与表达式

Rust语法可以分成两大类:语句和表达式
语句又分为两种:声明语句和表达式语句

  • 声明语句:用于声明各种语言项
  • 表达式语句:特指以分号结尾的表达式

Rust编译器在解析代码的时候,如果碰到分号,就会继续往后面执行;如果碰到语句则执行语句;如果碰到表达式,就会对表达式求值,如果分号后面什么都没有就会不上单元值()。
当遇到函数时,会将函数的花括号识别为表达式。块表达式是由一对花括号和一系列表达式组成的,它总是返回块中最后一个表达式的值。

2.3 变量与绑定、

2.3.1 位置表达式和值表达式

位置表达式就是表达内存位置的表达式,即左值,分别有以下几类:

  • 本地变量
  • 静态变量
  • 解引用(*expr)
  • 数组索引(expr[expr])
  • 字段引用(expr.field)
  • 位置表达式组合

求值上下文分为位置上下文和值上下文。下面几种表达式属于位置上下文:

  • 赋值或者符合赋值语句的左侧的操作数
  • 一元引用表达式的独立操作数
  • 包含隐式借用的操作数
  • match判别式或let绑定右侧在使用ref模式匹配的时候也是位置上下文。

2.3.2 不可变绑定和可变绑定

2.3.3 所有权与引用

1.to_string 没有出现书上说的“other value used here after move"
在语义上,每个变量绑定实际上都拥有该存储单元的所有权,这种转移内存地址的行为就是所有权的转移,在Rust中称为移动语义,那种不转移的情况实际上是一种复制语义
2.代码清单2-6中的b,实际代码中并没有打印地址,而是打印了数组

2.4 函数与闭包

2.4.1 函数定义

2.4.2 作用域与生命周期

2.4.3 函数指针

2.4.5 CTFE 机制 编译时函数执行

2.4.6 闭包

闭包有以下几个特点:

  • 可以像函数一样被调用
  • 可以捕获上下文的自由变量
  • 可以自动推断输入和返回的类型

2.5 流程控制

2.5.1 条件表达式

2.5.2 循环表达式

  • for n in
  • while
  • loop
    rust 编译器在对while循环做流分析的时候不会检查循环条件,while条件表达式无法作为编译器常量来使用。

2.5.3 match表达式与模式匹配

warning: ... range patterns are deprecated
--> src/main.rs:5:10
|
5 | 1...3 => println!("All"),
| ^^^ help: use ..= for an inclusive range
|
= note: #[warn(ellipsis_inclusive_range_patterns)] on by default

warning: 1 warning emitted

2.5.4 if let 和 while let 表达式

2.6 基本数据类型

2.6.1 布尔类型

可以通过as操作符将布尔类型转换为数字0和1,但是不支持数字转换为布尔类型

2.6.2 基本数字类型

2.6.3 字符类型

在Rust中,使用单引号来定义字符类型。字符类型代表的是一个Unicode标量值,每个字符占4个字节。
可以使用as操作符将字符转为数字类型。

2.6.4 数组类型

数组的特点是:

  • 数组大小固定
  • 元素均为同类型
  • 默认不可变
    数组的类型签名为[T;N]
    对于原始固定长度数组,只有实现Copy trait 的类型才能作为其元素,也就是说,只有可以在栈上存放的元素才可以存放在该类型的数组中。

2.6.5 范围类型

2.6.6 切片类型

在底层代表一个指向数组起始位置的指针和数组长度。
切片提供了两个const 方法 len 和is_empty ,分别用来得到切片的长度和判断切片是否为空

2.6.7 str字符串类型

Rust提供了原始的字符串类型str,也叫做字符串切片。它通常以不可变借用的形式存在,即&str。出于内存安全的考虑,Rust将字符串分为两种类型,一种是固定长度字符串,不可随便更改其长度,就是str字符串;另一种是可增长字符串,可以随意改变其长度,就是String字符串。
本质上字符串字面量也属于str类型,只不过它是静态生命周期字符串&'static str。
str字符串类型由两部分组成:指向字符串序列的指针和记录长度的值。可以通过str模块提供的as_ptr和len方法分别求得指针和长度。

2.6.8 原生指针

2.6.9 never 类型

never 类型用于表示永远不可能有返回值的计算类型

Rust小例子积累

从stream读取信息

从文件

fn func()->Result<(),Box<dyn Error>>{
    let path = "test.txt";
    let file = File::open(path)?;
    // if let Ok(file) = File::open(path){
    let buf = BufReader::new(file);
    for line in buf.lines(){
        if let Ok(l)= line{
            println!("{}",l);
        }
    }
    // }
    Ok(())
}

需要注意的问题

  1. ?不能在没有返回值的方法内使用
posted @ 2020-09-20 22:07  Fake_coder  阅读(372)  评论(0编辑  收藏  举报