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

\;\\\;\\\;

相关推荐
AI向前看4 分钟前
Perl语言的文件操作
开发语言·后端·golang
李匠20244 分钟前
Scala分布式语言二(基础功能搭建、面向对象基础、面向对象高级、异常、集合)
开发语言·后端·scala
Quantum&Coder10 分钟前
Dart语言的数据结构
开发语言·后端·golang
灵哎惹,凌沃敏24 分钟前
华为C语言编程规范总结
c语言·开发语言
雨 子33 分钟前
SpringBoot环境和Maven配置
java·spring boot·后端·java-ee·maven
zyplanke33 分钟前
Spring配置文件中:密码明文改为密文处理方式(通用方法)
java·后端·spring
计算机毕设指导637 分钟前
基于Springboot的景区民宿预约系统【附源码】
java·开发语言·spring boot·后端·mysql·spring·intellij idea
计算机毕设指导640 分钟前
基于Springboot美食推荐商城系统【附源码】
java·前端·spring boot·后端·spring·tomcat·美食
pumpkin845141 小时前
什么是 LuaJIT?
开发语言
云端 架构师1 小时前
Lua语言的语法
开发语言·后端·golang