【Rust】快速教程——闭包与生命周期

前言

你怎么向天生的瞎子说清颜色?怎么用手势向天生的聋子描述声音? 鲜花就在眼前,雷鸣就在头顶,对他们来说却都毫无意义 眼睛看不到,鼻子可以嗅闻花香,耳朵听不见,手指可以触碰窗纸的震动。 犯错的可能是描述者,而不是瞎子和聋子:你明知道他们无法领会颜色与声音,为什么非要生硬地灌输呢?换一种方法,用他们能理解的方式,同样能传递信息。------《拔魔》


         \;\\\;\\\;

目录

借用

借用borrow很像是引用reference,也就是地址。但是有限制,不能借用多次,即不能借用完了还当借用在自己这

rust 复制代码
fn main() {
    let mut s = String::from("hello");

    let a = &mut s;
    let b = &mut s; //不安全,报错,怎么能把可变的借用给两个ID

    println!("{}, {}", a, b);
}

         \;\\\;\\\;

生命周期

rust 复制代码
fn main() {
    // let r;
    // {
    //     let a = 5;
    //     r = &a;
    // }
    // println!("r={}", r); //报错,因为a被回收了
    

    let r;
    {
        let a = 5;
        r=a; //这样就没错了,因为这里是拷贝了一份
    }
    println!("r={}",r);

}
rust 复制代码
fn main() {
    let s=max("hola","hello");
    println!("s={}",s);
}


//fn max(x:&str,y:&str)->&str{ //报错,因为没指明两个参数的作用域
fn max<'a>(x:&'a str,y:&'a str)->&'a str{
    if x.len() > y.len(){
        x
    }
    else{
        y
    }
}

'a 进行声明周期标注,比如 'static 就是标注为全局静态。

rust 复制代码
fn main() {
    let a=String::from("hola");
    {
        let b=String::from("hello");
    }
    println!("max is {}",max(&a,&b)); //报错,b被回收了
}

fn max<'a>(x:&'a str,y:&'a str)->&'a str{
    if x.len() > y.len(){
        x
    }
    else{
        y
    }
}
rust 复制代码
#[derive(Debug)]
struct MyPack<'a> {
    part: &'a str, 
//    tally:&'b str,
}

fn main() {
    let i;
    {
        let a: String = String::from("test... i. t.."); //待分割的字符串

        let b: &str = a.split(".").next().expect("not find .");

        i = MyPack { part: b };
    }
    println!("part : {:?},", i); //错误,因为b被释放了
}

         \;\\\;\\\;

rust 复制代码
#[derive(Debug)]
struct Foo;

impl Foo{
    //传入可变借用,传出不可变借用(没有mut)
    //就是把可变借用转化为了不可变借用
    fn exec(&mut self)->&Self{
        &*self  //取星号是为了和传入的&抵消,不然&self就变成了地址的地址了
    }
    fn run(&self){
        println!("2");
    }
}


fn main(){
    let mut f : Foo = Foo;//f是可变的
    f.run(); //f是可变的
   
    let a : &Foo = f.exec(); //a是可变的,f借用给了a,所以下面f调用就出错了
   // println!("{:?}",a); //Foo
    f.run(); //只要后面有打印,就报错???
    //println!("{:?}",a); //Foo f.run()后面没有这句打印,就没错了

    println!("---------------------");
    {
        let mut b : Foo = Foo;//b是可变的
        {
            b.run();
            let c : &Foo = b.exec(); //c也是不可变的
            {
                //b.exec();
                //b.run();
                //c.exec();
                c.run(); //不可变的c可以调用run
            }
            println!("{:?}",c);
        }
    }
}
rust 复制代码
#[derive(Debug)]
struct Foo;

impl Foo{
    fn exec(&mut self)->&mut Self{
        &mut *self 
    }
    fn run(&self){
        println!("2");
    }
}


fn main(){
    {
        let mut b : Foo = Foo;//b是可变的
        {
            b.run();
            let c : &mut Foo = b.exec(); //c是可变的
            {
                //b.exec();
                //b.run();
                c.exec();
                c.run(); 
            }
            println!("{:?}",c);
        }
    }
}

         \;\\\;\\\;

闭包

就是lambda表达式,也是匿名函数

rust 复制代码
fn main(){
    let x:f64=100f64;
    let add = |y:f64| x+y  ;     //闭包
    let sub = |y| ->i64 { (x-y) as i64 };
    let one = ||1;

    println!("add : {}",add(20f64));
    println!("sub : {}",sub(20f64));
    println!("one : {}",one());
}

         \;\\\;\\\;

相关推荐
weixin_440784115 小时前
【HandlerThread实现原理】
android·java·开发语言
天空'之城5 小时前
C 语言工业级通用组件手写 24:互补滤波
c语言·开发语言·互补滤波·嵌入式算法·工业级组件
有梦不弃5 小时前
模块化单体架构设计方案:DDD + 六边形架构落地实践
后端·架构
XR1234567885 小时前
工厂车间无线网络方案对比:AGV漫游哪家强?
开发语言·php
傻啦嘿哟6 小时前
某短视频平台视频爬虫实战:抓取推荐流视频信息,绕过反爬的3种技巧
开发语言·爬虫·python
現実君6 小时前
【硬件进阶】AD22上位替换JLEDA教程
开发语言·php
mubei-1236 小时前
SpringDAO的用法
java·开发语言·数据库
格林威9 小时前
多相机微秒级对齐:硬件触发 vs PTP(IEEE 1588)方案实战对比
开发语言·人工智能·数码相机·机器学习·计算机视觉·视觉检测·机器视觉
江南十四行9 小时前
Spring框架核心(上)——IoC控制反转与DI依赖注入详解
java·后端·spring
IT_陈寒10 小时前
Redis缓存击穿把我坑惨了,原来这样设过期时间才靠谱
前端·人工智能·后端