Rust: lifetime
Rust的lifetime算是它最重要的特性之一,也不大好理解,特别是官方文档的介绍有些太过简略,容易让人误解。
这篇文章:
Rust Lifetimes
应该可以解答很多人疑惑,特别是有关lifetime的一些基础性的知识。
同时,参照其它的文章,在于总结一下关于Rust语言里的lifetime语法。
1. “lifetime”是指谁的lifetime?
lifetime是指reference的lifetime。它并不对应资源的生命周期,那是由move和borrow来控制的。同样,函数也是没有生命周期的,所以函数
fn foo<'a>(c: &'a i32) -> &'a i32
里的'a跟函数本身在何处被使用没有关系,它是被参数c的生命周期赋值的。
同时,&'a代表了一个生命周期为a的引用, 它们是一起的,比如,不会有&mut 'a,而是得写成&'a mut.
2. lifetime用来做什么?
来让编译器可以确定访问一个reference引用的对象是否安全。可以确保不会发生“use after free"错误,因此能让数据被安全地共享。
3. lifetime的值?
是什么?
首先,得明确一个”reference"的生命周期是什么?
fn foo() {
let a = &1;
let b = a;
...
}
一个reference的生命周期就是指在哪个代码区间可以用这个reference。比如,在上边的例子中,a可以在第2行至第4行被使用,b可以在第3行至第4行被使用。这个范围在代码编译时就确定了,不会延伸到任何其它区域,因为reference并不存在move和borrow这种语法,reference始终都是按值copy的。
还有一个隐晦但我不能确定的地方,从各种例子上看,假如我们在第4行去评估a和b的lifetime,那么它们是相等的。所以,看起来当lifetime被真正求值的时候,它的值的起点是被求值的那一行,终点是它不能再被使用的地方(在上例中是最后一个花括号)。
如何赋值?
lifetime的抽象程序使得它不合适程序员显式地指明其值。每个reference相关的lifetime的值都是由编译器确定的。
程序员能做的是将一个reference传给函数,同时这个reference的lifetime也会被传给这个函数作为参数。例如:
fn main() {
let a = &1;
let b = a;
let c = foo(a, b);
println!("{}", c);
}
fn foo<'a>(first: &'a i32, second: &'a i32) -> &'a i32 {
return second;
}
在调用foo时,a和b的lifetime被传给foo,使得foo的签名中的'a有了确定的值,因此返回值的lifetime也被确定。此时,如果返回值被赋值到的引用的lifetime比'a大,那么编译器就会报错。
注意,这里c的lifetime可以比'a要小,这里的小是指,它的lifetime被'a包括。
比如,可以这样:
fn main() {
let a = &1;
let b = a;
{
let c = foo(a, b);
}
println!("{}", a);
}
4 编译器检查lifetime的规则是什么?
这个可以看这篇文章:生命周期( Lifetime )
要推导Lifetime是否合法,先明确两点:
- 输出值(也称为返回值)依赖哪些输入值
- 输入值的Lifetime大于或等于输出值的Lifetime (准确来说:子集,而不是大于或等于)
Lifetime推导公式: 当输出值R依赖输入值X Y Z ...,当且仅当输出值的Lifetime为所有输入值的Lifetime交集的子集时,生命周期合法。
Lifetime(R) ⊆ ( Lifetime(X) ∩ Lifetime(Y) ∩ Lifetime(Z) ∩ Lifetime(...) )
Rust: lifetime的更多相关文章
- Rust <8>:lifetime 高级语法与 trait 关联绑定
一.生命周期关联:如下声明表示,'s >= 'c struct Parser<'c, 's: 'c> { context: &'c Context<'s>, } ...
- Rust: move和borrow
感觉Rust官方的学习文档里关于ownship,borrow和lifetime介绍的太简略了,无法真正理解这些语法设计的原因以及如何使用(特别是lifetime).所以找了一些相关的blog来看,总结 ...
- Rust入门篇 (1)
Rust入门篇 声明: 本文是在参考 The Rust Programming Language 和 Rust官方教程 中文版 写的. 个人学习用 再PS. 目录这东东果然是必须的... 找个时间生成 ...
- A First Look at Rust Language
文 Akisann@CNblogs / zhaihj@Github 本篇文章同时发布在Github上:http://zhaihj.github.io/a-first-look-at-rust.html ...
- 【转】对 Rust 语言的分析
对 Rust 语言的分析 Rust 是一门最近比较热的语言,有很多人问过我对 Rust 的看法.由于我本人是一个语言专家,实现过几乎所有的语言特性,所以我不认为任何一种语言是新的.任何“新语言”对我来 ...
- rust 参考的资料 转
http://blog.csdn.net/loveisasea/article/details/46292715 rust官方学习文档: 1.http://doc.rust-lang.org/book ...
- 2.4 Rust Ownership
What Is Ownership ownership这个单词有些不好翻译,刚开始就直接叫它“ownership”即可.这里简单说一下,我对它的理解, 从“数据结构与算法”的角度来看,ownershi ...
- Rust 内存管理
Rust 内存管理 Rust 与其他编程语言相比,最大的亮点就是引入了一套在编译期间,通过静态分析的方式,确定所有对象的作用域与生命周期,从而可以精确的在某个对象不再被使用时,将其销毁,并且不引入任何 ...
- Rust所有权语义模型
编程语言的内存管理,大概可以分为自动和手动两种. 自动管理就是用 GC(垃圾回收)来自动管理内存,像 Java.Ruby.Golang.Elixir 等语言都依赖于 GC.而 C/C++ 却是依赖于手 ...
随机推荐
- Flask Web Development —— Web表单(上)
Flask-WTF扩展使得处理web表单能获得更愉快的体验.该扩展是一个封装了与框架无关的WTForms包的Flask集成. Flask-WTF和它的依赖集可以通过pip来安装: (venv) $ p ...
- Learning Scrapy笔记(七)- Scrapy根据Excel文件运行多个爬虫
摘要:根据Excel文件配置运行多个爬虫 很多时候,我们都需要为每一个单独的网站编写一个爬虫,但有一些情况是你要爬取的几个网站的唯一不同之处在于Xpath表达式不同,此时要分别为每一个网站编写一个爬虫 ...
- 4.python中的用户交互
学习完如何写'hello world'之后,我们还是不太满意,因为这样代码就写死了,以后运行的时候都只打印一局固定的话而已. 但是,我想在程序运行后,自己手动输入内容怎么办,此时就要学习如何使用用户交 ...
- IOS笔记 : addChildViewController
一下addChildViewController,一个ViewController可以添加多个子ViewController,但是这 些子ViewController只有一个是显示到父视图中的,可以通 ...
- 【PHP】PHP中的类与对象
面向对象并不是PHP的关键,但PHP确实能很好的支持面向对象编程,而且类与对象也成为了PHP5的核心组成部分.PHP的面向对象特性让构建大型的复制应用成为可能,有了类与对象,就自然产生了各种编程范式和 ...
- MAC下安装与配置MySQL [转]
一 下载MySQL 访问MySQL的官网http://www.mysql.com/downloads/ 然后在页面中会看到“MySQL Community Server”下方有一个“download” ...
- hdu 4217 Data Structure?/treap
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4217 可用线段树写,效率要高点. 这道题以前用c语言写的treap水过了.. 现在接触了c++重写一遍 ...
- android开发系列之git常用命令
最近因为跳槽到新公司,然后新公司里面的代码管理工具是gitLab,所以我想在这篇博客里面整理一下git常用的语法. GitLab是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托 ...
- python生成带参数二维码
#coding:utf8 import urllib2 import urllib import json import string import random class WebChat(obje ...
- Zybo智能小车识别图像中的文字
智能小车识别图像中的文字 [TOC] 运行平台 这次的内容是基于Xilinx公司的Zybo开发板以及其配套的Zrobot套件开发 Zybo上面的sd卡搭载了Ubuntu12.04LTS的linux版本 ...