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

         \;\\\;\\\;

相关推荐
吾皇斯巴达几秒前
O_DIRECT与gcsfuse的go程序中实现内存页面对齐
开发语言·后端·golang
光电的一只菜鸡17 分钟前
高通tuning中eis需要调什么
java·开发语言·前端
兔兔兔兔119 分钟前
记录C++ 12
开发语言·c++
丰锋ff36 分钟前
基于 Qt 的智能门禁系统(三)
开发语言·qt
消费知多少1 小时前
解析勤策签约大西洋焊接费用核销实践案例
开发语言·c#
马可家的菠萝1 小时前
收藏不是终点:一个真正有用的个人知识库,至少要完成“收集 → 理解 → 行动”
前端·后端·架构
东小西1 小时前
【SAA实战】第 2 篇:模型与消息——ReactAgent 怎么挑模型、怎么传消息
java·后端·spring
LabVIEW开发1 小时前
LabVIEW按段拆分TDMS文件的格式边界与重构
开发语言·数据库·重构·labview·labview知识·labview功能·labview程序
qo_tn1 小时前
Docker_02-容器操作_11-怎样进入容器执行命令
后端
架构精进之路2 小时前
Claude Code 深度使用指南:从"会用"到"用好"的7个进阶心法
后端·openai·ai编程