Rust 基础再理解

Rust堆栈

Rust中各种类型的值默认都存储在栈中,除非显式地使用Box::new()将它们存放在堆上,但数据要存放在栈中,要求其数据类型的大小已知。对于静态大小的类型,可直接存储在栈上,如裸指针、布尔、字符、整数浮点数,数组等。
动态大小的(Vecstring)都是存堆的
一些注意事项

  • 栈中的数据赋值给变量的时候,数据是直接放在栈中的。
  • 类型的值都默认放在栈中,所以创建引用的时候,引用的是栈里的值。
  • 容器中保存的是原始类型的栈里的值或者指向堆数据的引用
  • 字符串字面量,static静态变量都会硬编码嵌入到二进制程序的全局内存区
  • const定义的常量,会在编译期间直接以硬编码的方式内联插入到使用常量的地方,即,直接硬编码到对应代码行。同时函数也可以内联,即函数对应代码体会直接展开并插入到调用函数的地方,省去调用函数的开销。

位置与值

位置:某一块内存位置,它有自己的地址,有自己的空间,有自己所保存的值。
:存储到位置中的数据(即保存在内存中的数据)
位置的产生

  • 会产生变量的时候(初始化)
  • 需要保存某个值的时候(函数调用参数和返回值)
  • 产生新的值(引用,解引用)

let 语句

let a = 1;
a:为变量名,也是对内存位置的一个可读代号,编译期间会被替换为更低级的代号或者直接为地址。也就是位置,是存值1的一块内存。
每个位置就是它所放值的所有值,因为每个值都只能存放在一个位置中,所以每个值都只能有一个所有者。
let v = vec![1, 2, 3, 4];
v:位置,代表栈中的一块内存,值是一个指针地址,实际数据是放在堆里的。

引用

Rust的引用是一种原始数据类型,位置仍然是栈里,保存的值和指针一样,是一个地址。该地址指向了**位置(**也就是前面的av

let n = 33; // 假设n的地址为0x234
let nn = &n; // 假设nn的地址为0x123

那么,nn的位置是0x123,它存的值是0x234,也就是n的地址。
编译器维护栈内存,所以它知道栈中的某个内存是否安全,而堆内存由程序员自己负责,程序员自己的行为是无法保证安全的。
所以,Rust的行为模式是将是涉及到内存安全的概念扔到栈上,让程序员远离对堆的操作。所以,允许允许对栈中同一个数据的多个指向,不允许对堆中同一个内存的多个指向,即变量存在多个引用,但所有权只能有一个

位置的属性

位置的属性和状态都由编译器在编译期进行维护。
位置有类型,有标记(是否被引用,可变引用还是不可变,共享还是独占等等),根据位置的类型是否实现Copy Trait来决定该位置的是拷贝还是移走。

所有权和借用

变量作用域

我们知道rust 变量在脱离作用域之后就会被销毁,但事实是,变量在跳出作用域时,会自动Drop Traitdrop函数来销毁内存中堆和栈的数据,全局内存中的数据是从程序启动到终止期间一直存在。
另外rust的作用域为一对大括号{},大括号的作用域是可以访问大括号外部的变量,而在函数的作用域内则不行,这被称为捕获环境,函数是不能捕获环境的,而大括号可以捕获环境

数据的拷贝

由于所有权问题和变量脱离作用域而引起的内存二次释放问题,rust是不允许有两个指针同时指向同一块内存的。所以rust 没有浅拷贝和深拷贝的概念,取而代之的是movecopyclone

  • move:也就是转移所有权,涉及到的过程是拷贝到目标变量,同时会将原来的变量设置到未初始的状态。rust 默认使用的就是move

当使用值的时候,就会产生位置,那么就会发生移动。解引用,字段访问,索引访问等都会隐式移动。

  • copy:和move的区别就是,拷贝之后原来的变量还是可以用。如果要使用copy,就需要要拷贝的数据类型实现了Copy Trait,手动实现的时候需要同时实现Clone Trait
  • cloneclonecopy很接近,区别在于,
  • Copy时,只拷贝变量本身的值,如果这个变量指向了其它数据,则不会拷贝其指向的数据。
  • Clone时,拷贝变量本身的值,如果这个变量指向了其它数据,则也会拷贝其指向的数据。

函数调用之后也是会转移所有权的,有时候这样是很不方便的,所以在传参的时候可以传递到变量的引用,引用时保存在栈里,也实现了Copy Trait,这样效率会更高。

可变引用的排他性

不可变引用是可以共存的,但是可变引用具有排他性,在同一作用域同一数据只能有一个。
这里的排他性,应该看作一把独占锁,在当前作用域内,从第一次使用可变引用开始创建这把独占锁,之后无论使用原始变量(即所有权拥有者)、可变引用还是不可变引用都会抢占这把独占锁,以保证只有一方可以访问数据,每次抢得独占锁后,都会将之前所有引用变量给锁住,使它们变成不可用状态。当离开当前作用域时,当前作用域内的所有独占锁都被释放。

回顾一下可变引用的几个性质

  • 同一作用域,特定数据只能有一个可变引用
  • 可变借用不能用于不可变借用上
  • 有了可变借用就不能再有不可变借用
  • 引用作用域和变量作用域不一样,它的结束位置再最后一次使用的位置

自从第一次使用可变引用导致独占锁出现后,可以随时使用原始变量、可变引用或不可变引用来抢独占锁,但抢锁后以前的引用变量就不能再用,且当前持有的锁也可以随时被抢走。不可变引用抢占之后所有的包括自身都是不可用的,但再次使用可变引用抢占锁之后,该可变引用是可用的。
一切都由程序员控制,程序员可以在任意代码位置通过原始变量或引用来抢锁。

模式匹配

rust中可分为

  • 不可反驳的模式(irrefutable):一定会匹配成功,否则编译错误,如let赋值,for迭代,函数传参等。
  • 可反驳的的模式(refutable):可以匹配成功,也可以匹配失败,匹配失败的结果是不执行对应分支的代码,如if letwhile let

match匹配支持两个模式

  • 当明确给出分支的Pattern时,必须是可反驳模式,这些模式允许匹配失败
  • 使用_作为最后一个分支时,是不可反驳模式,它一定会匹配成功
  • 如果只有一个Pattern分支,则可以是不可反驳模式,也可以是可反驳模式

再谈Trait

组合

Trait最基本的作用是从多种类型中抽取出共性的属性或方法,主要表现为泛型数据类型。可以理解为,它描述了一种通用的功能,功能都要求具有某些特殊的行为,同时功能可以被很多种类型实现。
同样,一个类型也可以实现很多种Trait,组合出很多功能,这和一般面向对象编程语言的继承有所不同,不用继承冗余的功能,而更加的自由。
组合和继承的关系可以理解为 **has a **和 is a 的关系。

特征对象

也就是具有某个特征功能的类的实例。
上篇提到过,Duck Typing ,也就是只需要叫起来想鸭子,就可以当成鸭子来使用。(只需要你会打螺丝,不管你是不是大学生。)
这里的意思就是,实现了某个特征的众多对象都具有该功能,而由于 Trait 自身不能当作数据类型来用(因为,可能一种类型实现了很多中 Trait,显然无法用一种 Trait 来代替这种数据类型)。因此就诞生了 Trait Object,也就是将实现了 Trait A 的类型 B,C,D 当作 Trait ATrait Object使用。(可以类比为继承里的父类)

Trait object的创建是通过&dyn T或者指针Box<dyn T>Rc<dyn T>等等
本质就是由于 Trait object 的大小是不定的,所以选择将引用存在栈中,包含两部分数据

  • 指向数据的指针:指向实现了Trait的具体类型的实例,
  • 指向一个虚表 vtable 的指针:因为实现了 Trait 的类型有很多,而每个类型拥有的方法时各不相同的,所以需要一个虚表来区分保存。虚表中保存了实例可以调用的,实现的来自特征 Trait 的方法。当该对象调用方法时,直接从虚表中找到方法,然后调用。

其他

  • StructEnum类型需要手动实现Trait,即,使用#[derive()]
  • 特征是支持继承的,如
trait B{}
trait A: B{}

当类型想实现 Trait A 的时候,需要要求同时实现 Trait B

参考

Rust入门秘籍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Rust权威指南是一本深入介绍Rust编程语言的权威性书籍。这本书主要介绍Rust语言的基本语法和特性,包括Rust的所有关键字、数据类型、函数、模块、宏、”生命周期”、所有权等重要概念的详细解释和使用方法。 这本书由Rust社区知名的开发者Steve Klabnik和Carol Nichols撰写,是Rust开发者及其他想要学习Rust编程语言的程序员的必读之作。书详细介绍了Rust的语法规则和特性,如何编写高质量、高性能的Rust代码,以及如何使用Rust来进行并发编程和系统级编程。 通过阅读本书,读者能够了解Rust的核心概念,如所有权、生命周期和借用,以及如何使用Rust的工具链进行开发。在本书的后半部分,作者通过实践案例和示例向读者展示了如何使用Rust来编写高效、可靠的程序。 总的来说,Rust权威指南是一本非常实用且详尽的Rust编程语言指南,对于想要学习Rust编程语言的读者非常有益。不仅提供了基础知识方面的介绍,还给读者提供了诸如性能优化等高级内容的指导。同时,本书也适合那些已经有一定Rust编程经验的读者,它们可以通过本书深入了解Rust语言内部之间的联系。 ### 回答2: 《Rust权威指南》是一本针对Rust编程语言的详细讲解和指导的权威指南。该书由Rust的核心开发人员编写,涵盖了Rust语言的基本概念、语法、数据类型、内存管理、并发编程、错误处理、泛型、宏等方面,旨在帮助读者全面深入地学习和理解Rust语言。 该书内容广泛,详细全面,适合初学者和有经验的开发人员。书每一章都有大量的代码示例,并附有解释和注释,易于理解。书还介绍了Rust的生态系统和常用开发工具,如包管理器Cargo、测试框架等。 此外,《Rust权威指南》还强调了Rust语言的安全性和性能优势。Rust通过静态类型检查、所有权系统、借用规则等机制,大大减少了程序运行时的内存安全问题。同时,Rust的设计和实现也使得其具有与C++类似的性能优势。 总的来说,《Rust权威指南》是一本权威性强、内容深入的Rust编程指南。对于想要学习Rust编程语言的开发人员来说,这本书绝对是一本值得购买和阅读的好书。 ### 回答3: 《Rust权威指南》是一本全面介绍Rust语言的书籍,该书由Rust文社区的翻译小组翻译而成。这本书详细讲解了Rust语言的语法、基础知识、数据类型、控制流、函数、模块、生命周期、所有权系统等内容,涵盖了Rust语言的各个方面。 这本书的特点在于其权威性和全面性。作为Rust语言的权威指南,该书不仅涵盖了Rust语言基础知识,还深入讲解了Rust语言的高级特性,如内存管理、安全性、并发等方面。此外,书还包括了大量的实例和案例,可以帮助读者更深入地理解Rust语言。 对于初学者来说,该书可以作为Rust语言的入门指南。对于已经掌握了Rust语言基础知识的读者来说,本书也可以作为进一步深入学习和实践Rust语言的指南。此外,该书还提供了完整的API文档和Rust语言的标准规范,方便读者进行参考和查阅。 总之,《Rust权威指南》是一本全面、详细、权威的Rust语言指南,适合Rust语言的初学者和进阶者。读者可以通过该书深入了解Rust语言并掌握其应用,提高自己的编程能力和实践经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值