本文的针对性:
上图是关于先前有关生锈的问题的问题
许多人有疑问:“为什么人们仍然推出一种新的生锈语言?”
有很多回答这个问题的想法:
您可能还会问:“但是我没有生锈的场景?”
这个问题可以更好地解决。只要您对行业中最具特征性的垃圾回收机制感兴趣,您肯定会从阅读中获得一定的收益。
您可能的最后一个问题:“我听说锈蚀学习曲线很众所周知,难以入门吗?”
确实,他的学习难度是众所周知的(可能比Java更困难),但是他的代码审查很难相对简单。您不好奇为什么有这样的现象吗?
堆栈(堆栈)和堆是可在运行时可以使用的存储空间。堆栈是常规结构,每个零件的大小等效,数据结构是先进的,并且堆的结构相对较宽。使用空间时必须合理分布。
一些数据类型(例如int/char)通常存储在堆栈中,堆栈大小是固定的,并且无需计算分配的空间,并且随着时间的推移时间较小。
以及一些非固定数据类型(例如JavaScript:Object / Rust:String),这些数据的实际内容将存储在堆中,并存储了诸如堆栈中的指针之类的数据。
JavaScript中的堆栈和堆栈
多亏了CPU高速缓存,处理器可以减少对内存的访问。高速缓存和内存之间的访问速度差异超过10次。堆栈数据通常可以直接存储在CPU高速缓存中,而堆数据只能存储在内存中。首先通过堆栈上的指针访问以访问内存。
想象一下,如果未释放存储在堆中的数据,并且它继续无限增加,我们的程序将不可避免地具有各种异常现象。
如果您是使用某种高级编程语言(JavaScript/Java/Python等)的开发人员,那么您可能对垃圾回收机制了解不多。
例如,JavaScript,因为JavaScript引擎可以帮助您完成所有操作,因此开发人员无需过分关注代码级别的内存开销的影响。
全名,什么是“垃圾”?在程序开发过程中,我们将使用一些系统内存。当使用某个内存时,我们需要回收。如果未回收,则该内存将始终被占用并且无法重复使用。严重的记忆泄漏会导致程序卡死亡。
如下图所示,JS堆的大小以一个步骤上升:
在大多数业务情况下,全自动垃圾回收能力看起来非常漂亮。它大大减轻了开发人员在记忆控制方面的精神负担。我们可以专注于需要继续的其他观点。
在偏向系统级别的基础技术领域(例如音频和视频客户端)中,我们对内存占用成本的要求更高。目前,内存管理的优化使我们发挥了拳头。
C/C ++带来“自由”记忆管理是无情的双刃剑,“自由”也伴随着无尽的错误和更高的代码理解成本。这次,为什么不需要Rust?Rust不需要开发人员即可执行空间应用程序/发布和其他操作。为了照顾更好的绩效,它介绍了特殊[所有权]和[生命周期]的概念。它可以确保安全性并且在执行过程中不会带来绩效费用。
所有权是控制RUST程序如何管理内存的一组规则。
只需解释以下规则:我们每个人只有一个所有者,当所有者失败时,此值不存在。
让我们看一下Rust类型的弦乐类型,它比Int/Char等类型更为特殊
字符串::来自:从字符串的字符串创建
如果以上逻辑出现在JS / Java中,则只是一个非常简单的分配过程,并且可以顺利实现。Rust只需要每个所有者。当执行第三行时,“ Hello”的所有者将变为S2。目前,再次打印S1,我们只会收获一个错误。
该图被描述为下图:堆栈中的S1将“ Hello”的所有权转移到S2,而S1无效。
假设如果S1不是无效的,则在编译阶段回收数据时,Rust会发现两个指针指向相同的内存,并且“索引”的内存将被错误发布两次!内存污染,可能导致潜在的安全漏洞。
如果我们想让S1正常打印,我们必须复制一个“ Hello”,如下所示:
Rust永远不会自动创建复杂数据类型的“深层复制”,因为这太大了,对于内存开销而言,我们必须在需要时手动调用它。
如果我们想使用int类型数据:
上述代码可以正常执行,因为X是一种简单的类型(INT),它是可以存储在堆栈中的数据类型。这次,Rust将帮助我们在堆栈中复制副本,因为在堆栈非常快。
如果我们的所有权仅仅是独特的归属,那么它将不可避免地增加我们的编码困难。让我们看一下报价。
报价分为可变参考和不令人满意的参考文献:
r是x的难以言喻的参考(参考是内存(非持有)指针类型中另一个值的非所有权)
当我们想使用指针指向变量并想要更改此变量时,我们还会使用变量参考(&mut):
由于Rust的新编译器和旧编译器之间的差异,该编译是否不同:
令mut s定义可变s
令R1 =&S;R1是对S的不可用的引用,即指向相应的内存指针
令r3 =&mut s;R3是对S的变量引用,然后可以更改S
由于空间,我们仅简要介绍了引用的相关知识。我希望更多了解更多的学生可以在以后阅读深度学习材料。
简而言之,生命周期是有效的范围。在某些情况下,我们不需要手动声明生命周期,因为编译器可以自动得出。
以上代码将在编译时间报告错误:因为“ X”无法生存那么长时间。
在Rust,从数据定义到一对括号的结尾,它是一个生命周期范围(请参阅上图中的“ a和b”),a是r的生命周期,b是生命周期,b是生命周期X和X的生命周期小于R,因此在执行后,X的生命周期结束了。目前,R指向回收数据的地址并成为垂直指针,因此是错误的。
当函数在参数中出现中的功能时,可能会稍微粗心大意,因此生锈的编译器比我们更紧张:
以上是判断字符串长度的函数。看起来完全可以,但实际上会报告一个错误:
此错误的原因是生锈无法推断X和Y!的生命周期!因为编译器无法分析返回X或Y,因此我们必须明确声明参数的生命周期。
生命周期的格式如上所述,让我们现在修改代码:
您现在可以正常运行!
首先,请记住:生命周期标签不会改变任何参考实际范围
生命周期的标签仅仅是您正在教授编译器,这只是一个指导角色!
例如,因为我们的编译器有时非常聪明,所以它可以在某些简单场景的面前得出生命周期(当只有一个参数是参考类型时,如果可以正常编译,则回报值的生命周期为只有可能。它与此参数密切相关),但是复杂的场景通常不可能推测!
回到上一个示例,我们的标签可以解释:
如果我们不添加标签,对于Rust编译器,它实际上等同于:
Rust不能自动推断X返回值的生命周期是'a还是',因此我们需要手动“告知” Rust。
让我们简单地修改示例中的代码,以便String1和String2具有不同的生命周期,但是在最长的函数中,我们仍然将两个参数视为相同的生命周期:
字符串1的生命周期明显大于string2,结果是:
哈哈,出乎意料地报告了一个错误,并再次验证“生命周期标记不会改变任何参考实际范围”
您永远无法欺骗生锈的编译器?
这篇文章只是砖!Rust有很多值得研究的内容!
以下两篇文章基本上是必读的。本文的某些内容还涉及以下教程:
Rust Program设计语言-Rust程序设计语言简化了中文版本
输入Rust编程世界 - 绿地语言圣经(Rust Orcess)
第一个文档中发现的《宝藏视频》的第一个文档。
当老师讲话时,它将通过代码来证明,这比纯粹的文章更好(教师的东北口音也非常强烈,您听的越多)
https://www.bilibili.com/video/bv1hp4y1k7sv
https://juejin.cn/post/6981588276356317214
堆栈,堆栈和队列已经深入了解,访谈不用担心-nuggets
https://juejin.cn/post/6844904106310516744
原始:https://juejin.cn/post/7099362775621140510