【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());
}

         \;\\\;\\\;

相关推荐
郭小李9 分钟前
spring 中的 @EnableWebMvc注解和WebMvcConfigurer接口
java·后端·spring
马剑威(威哥爱编程)10 分钟前
Python 智能体开发实战 01:装了三遍环境还在报错?虚拟环境和 DeepSeek 一次配到位
开发语言·人工智能·python·agent
octopus_c14 分钟前
C++ 入门
开发语言·c++·算法
卷无止境15 分钟前
Skill 的安全边界在哪里:风险来源、验证思路与用户可用的防线
后端·python
步行cgn1 小时前
JSON.stringify 详解:把 JavaScript 对象变成 JSON 字符串
开发语言·javascript·json
星核0penstarry1 小时前
企业 API 向后兼容实战:版本控制、废弃字段通知与灰度发布策略
人工智能·后端·api·接口隔离原则·版本控制·架构设计·后端架构
Soneswy1 小时前
C++基础篇——类与对象(中)
开发语言·c++
CoderYanger1 小时前
Java EE 进阶:5. Spring IoC&DI(第二弹):Spring IoC
java·开发语言·spring boot·spring·面试·职场和发展·java-ee
用户别睡觉2 小时前
自己搭的中文 PDF RAG 接了 Redis 缓存、跑了 RAGAS,以为能写“提速多少、准确率多少”,结果两个都没按预期来。
后端
西风测评2 小时前
终端粘贴原理:bracketed paste、4095 字节行限制与 UTF-8 分片
rust