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

\;\\\;\\\;

相关推荐
sonrisa_11 分钟前
Python同一类不同方法中变量值的传递
开发语言·windows·python
星火开发设计23 分钟前
C++ 输入输出流:cin 与 cout 的基础用法
java·开发语言·c++·学习·算法·编程·知识
毕设源码-邱学长32 分钟前
【开题答辩全过程】以 基于Springboot的酒店住宿信息管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
曹牧1 小时前
Java:强类型转换
开发语言·python
wuguan_1 小时前
C#之线程
开发语言·c#
LXS_3571 小时前
STL - 函数对象
开发语言·c++·算法
木千1 小时前
Qt5.15.2安装MSVC2019编译器
开发语言·qt
仟濹1 小时前
【Java加强】1 异常 | 打卡day1
java·开发语言·python
去往火星1 小时前
Qt6 CMake 中引入 Qt Linguist 翻译功能
开发语言·qt
阿猿收手吧!1 小时前
【C++】atmoic原子操作与并发安全全解析
开发语言·c++·安全