转载

[易学易懂系列|rustlang语言|零基础|快速入门|(5)]

Lifetimes

我们继续谈谈生命周期(lifttime),我们还是拿代码来说话:

```

fn main() {  let mut a = vec![1, 2, 3];  let b = &mut a;  //  &mut borrow of a starts here  // some code

println!("{:?}", a); // trying to access a as a shared borrow, so giving an error}                  //  &mut borrow of a ends here

```

我们在上篇文章说到,这段代码:

println!("{:?}", a);

是过不了霸道的编译器女王的检查的?

为什么?

因为b借用了a的数据所有权,没有还回来。

所以,这时,访问a的数据时,编译器女王报错。

那要怎么办?加大括号 {}。

如下 :

fn main() {  let mut a = vec![1, 2, 3];  {    let b = &mut a;  //  &mut borrow of a starts here    // any other code  }                  //  &mut borrow of a ends here

println!("{:?}", a); // allow borrowing a as a shared borrow}

我们可以看到,b 的“生命周期”,是限定在大括号 {}中的。

我们来看一个更清楚的代码:

我们现在知道,可以用大括号来限定变量或引用的生命周期。但太多大括号,会让你看得头大。

[易学易懂系列|rustlang语言|零基础|快速入门|(5)]

没关系,rust都为你考虑到了。下面是生命周期定义的标准写法。

翠花,上代码 :

// No inputs, return a reference

fnfunction<'a>()->&'astr{}

// Single input

fnfunction<'a>(x: &'astr) {}

// Single input and output, both have the same lifetime

// The output should live at least as long as input exists

fnfunction<'a>(x: &'astr)->&'astr{}

// Multiple inputs, only one input and the output share same lifetime

// The output should live at least as long as y exists

fnfunction<'a>(x:i32,y: &'astr)->&'astr{}

// Multiple inputs, both inputs and the output share same lifetime

// The output should live at least as long as x and y exist

fnfunction<'a>(x: &'astr,y: &'astr)->&'astr{}

// Multiple inputs, inputs can have different lifetimes :mag_right:

// The output should live at least as long as x exists

fnfunction<'a, 'b>(x: &'astr,y: &'bstr)->&'astr{}

我们可以看到,rust用'a  这样的注解来标注“生命周期”,即:单引号字符+小写字母。

如果有多个生命周期,就用字典顺序,如:'a 'b 'c 'd,v如此类推。

那从上面 的代码注释,我们也很清楚的明白,如果定义是同一种生命周期的注解的变量或引用,它们应该是相同生命周期,用人类的话来说:命一样长。

好理解。

上面的例子,是用在函数上,那其他类型呢?

我们来看看Struct 和Enum类型

请看下面代码:

// Single element

// Data of x should live at least as long as Struct exists

structStruct<'a>{

x: &'astr

}

// Multiple elements

// Data of x and y should live at least as long as Struct exists

structStruct<'a>{

x: &'astr,

y: &'astr

}

// Variant with a single element

// Data of the variant should live at least as long as Enum exists

enumEnum<'a>{

Variant(&'aType)

}

我们看到,struct中的变量,定义为同一生命周期注解'a,则它们的“命一样长”。

也很好理解。

我们再看看接口实现和特征变量,如下 :

structStruct<'a>{

x: &'astr

}

impl<'a>Struct<'a>{

fnfunction<'a>(&self)->&'astr{

self.x

}

}

structStruct<'a>{

x: &'astr,

y: &'astr

}

impl<'a>Struct<'a>{

fnnew(x: &'astr,y: &'astr)->Struct<'a>{// No need to specify <'a> after new; impl already has it

Struct{

x:x,

y:y

}

}

}

// :mag_right:

impl<'a>Trait<'a>forType

impl<'a>TraitforType<'a>

再看看泛型:

// :mag_right:

fnfunction<F>(f:F)wherefor<'a>F:FnOnce(&'aType)

structStruct<F>wherefor<'a>F:FnOnce(&'aType) {x:F}

enumEnum<F>wherefor<'a>F:FnOnce(&'aType) {Variant(F) }

impl<F>Struct<F>wherefor<'a>F:FnOnce(&'aType) {fnx(&self)->&F{ &self.x} }

有同学说,如果每次写函数定义,都要显式定义生命周期注解。那不是很麻烦的一件事。

没关系,rust再次为你安排上了。

针对函数类型fn:

1.参数全部都是传递引用的函数可以直接这样定义:

..(x: &str, y: &str)

rust自动内部转化为:

..<'a, 'b>(x: &'a str, y: &'b str)

2.参数部分传递引用的函数可以直接这样定义:

..(x: i32, y: &str) -> &str

rust自动内部转化为:

..<'a>(x: i32, y: &'a str) -> &'a str

3.多个参数,有部分参数是&self或&mut self的传递引用函数:

impl Impl{ fn function(&self, x: &str) -> &str {} }

rust自动内部转化为:

impl<'a> Impl<'a>{ fn function(&'a self, x: &'b str) -> &'a str {} }

现在我们来看看静态生命周期注解: 'static

其实,就是类似java中的静态变量定义,它的生命周期是跟整个程序的生命周期一样,它一般用来定义全局变量。

如下:

staticN:i32=5;// A constant with 'static lifetime

leta="Hello, world.";// a: &'static str

fnindex()->&'staticstr{// No need to mention <'static> ; fn index ̶<̶'̶s̶t̶a̶t̶i̶c̶>̶

"Hello, world!"

}

如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust

本人精通java高并发,DDD,微服务等技术实践,以及python,golang技术栈。  本人姓名郭莹城,坐标深圳,前IBM架构师、咨询师、敏捷开发技术教练,前IBM区块链研究小组成员、十四年架构设计工作经验,《区块链核心技术与应用》作者之一, 现有成熟团队提供区块链开发相关业务(公链,交易所,钱包,Dapp,智能合约)。  工作微信&QQ:360369487,交易所开发与区块链钱包开发业务,加我注明:博客园+开发,想学习golang和rust的同学,也可以加我微信,备注:博客园+golang或博客园+rust,谢谢!

原文:https://www.cnblogs.com/gyc567/p/11910818.html

原文  https://studygolang.com/articles/24861
正文到此结束
Loading...