Rust 02.控制、引用、切片Slice、智能指针

1.控制流

//rust通过所有权机制来管理内存,编译器在编译就会根据所有权规则对内存的使用进行
//堆和栈
//编译的时候数据的类型大小是固定的,就是分配在栈上的
//编译的时候数据类型大小不固定,就是分配堆上的
fn main() {
    let x: i32 = 1;

    {
        let y: i32 = 1;
        println!("x = {}", x);
        println!("y = {}", y);
    }

    {
        let s1 = String::from("hello");
        //s1.push_str(" world");
        println!("s1 = {}", s1); //String类型离开作用域的时候会调用drop方法

        let s2 = s1; //浅拷贝 只是拷贝了指针, 数据并没有拷贝
        println!("s2= {}", s2);
        //println!("s1= {}", s1); //s1在被copy后会自动释放指针内存,所以会报错
        

        //clone 深拷贝数据
        let s3 = s2.clone();
        println!("s3= {}", s3);
        println!("s2= {}", s2);
    }

在这里插入图片描述

控制权

fn takes_ownership1(some_string: String){
    println!("{}", some_string);
}

fn takes_ownership2(some_string: String) -> String{
    println!("{}", some_string);
    some_string
}

fn makes_copy(i: i32) {
    println!("i = {}", i);
}

fn main() {
    let s = String::from("hello");
    //takes_ownership1(s); //s在调用函数后被drop,后续无法打印其值
    //println!("{}", s);
    let s2 = takes_ownership2(s);
    println!("{}", s2);

    let x = 5;
    makes_copy(x);
    println!("{}", x);
    println!("Hello, world!");
}

2.引用

//引用: 用法&,
//让我们创建一个指向值的应用,但是并不拥有它,因为不拥有这个值,所以,当引用离开其值指向的作用域后也不会被丢弃
fn calcute_length(s: &String) ->usize {
    s.len()
}

//借用:&mut 可以修改字符串,同时不会执行drop操作
fn modify_s(s: &mut String) {
    s.push_str(", world");
}

fn dangle() -> &String {
    let s = String::from("hello");
    &s
}

fn main() {
    let mut s1 = String::from("hello");
    
    //在任意给定时间,有了可变引用之后不能再有不可变引用
    let r1 = &s1;
    let r2 = &s1;
    println!("{}, {}", r1, r2);

    let r3 = &mut s1;
    r3.push_str(", world");
	//println!("{}, {}", r1, r2); 由于r3为 可变引用, r1,r2不能在这里使用,必须在r3之前使用
		
    //引用不能为空,dangle()中给s赋值结束后就drop了,最终返回了空指针,这是不合法的
    //let ref_s = dangle();
    //println!("{}", ref_s);
}

3.Slice

//1、字符串slice是String中一部分值的引用
//2、字面值就是slice
//3、其它类型slice
fn main() {
    let s = String::from("hello world");

    let h = &s[0..5]; 	//区间[0,5)
    let h = &s[0..=4]; 	//区间[0,4]
    let h = &s[..=4]; 	//区间[0,4]
    let h = &s[..5]; 	//区间[0,5)
    println!("h = {}", h);

    let w = &s[6..11];  //区间[6,11)
    let w = &s[6..=10]; //区间[6,10]
    let w = &s[6..];  	//区间[6,s.len())
    let w = &s[..]; 	//区间[0,s.len())
    println!("w = {}", w);

    //let ss = String::from("你好");
    //let w1 = &ss[0..1];

    let a = [1, 2, 3, 4];	
    let sss = &a[1..3];		//取a中[1,3)的元素
    println!("sss = {}", sss[0]);	//a[1]
    println!("sss = {}", sss[1]);	//a[2]
    println!("len = {}", sss.len());	//长度为2
}

4.智能指针

Box
fn main() {
    let text: String = "Hello CSDN".to_string();
    // 将字符串移动到堆上 
    let box_text: Box<String> = Box::new(text);
    // 此时原text已失效,因为所有权已经转移给box_text
    println!("{}", box_text);
}
Rc
use std::rc::Rc;
 
fn main() {
	//  Rc<T>提供了非独占、可共享的引用,它的内部维护了一个引用计数。当引用数量变为0时,会自动释放堆内存。
    let shared_data = Rc::new(66);
 
    // 创建指向同一数据的多个Rc实例
    let ref1 = Rc::clone(&shared_data);
    let ref2 = Rc::clone(&shared_data);
 
    println!("ref1: {}", ref1);
    println!("ref2: {}", ref2);
 
    // 当最后一个Rc实例超出作用域时,数据会被清理
}

相关推荐

  1. Rust 智能指针

    2024-03-31 05:40:05       49 阅读
  2. golang切片slice)详解

    2024-03-31 05:40:05       51 阅读
  3. Go语言 切片slice

    2024-03-31 05:40:05       28 阅读
  4. Rust引用借用 vs 原始指针

    2024-03-31 05:40:05       37 阅读
  5. Go 基础丨切片 slice

    2024-03-31 05:40:05       27 阅读
  6. Rust切片

    2024-03-31 05:40:05       44 阅读
  7. Go 源码之切片 Slice

    2024-03-31 05:40:05       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-31 05:40:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-31 05:40:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-31 05:40:05       87 阅读
  4. Python语言-面向对象

    2024-03-31 05:40:05       96 阅读

热门阅读

  1. OpenKylin安装Redis

    2024-03-31 05:40:05       36 阅读
  2. c语言-生成随机数、获取当前年月日时分秒

    2024-03-31 05:40:05       44 阅读
  3. GFW不起作用

    2024-03-31 05:40:05       37 阅读
  4. Redis的基础命令详解

    2024-03-31 05:40:05       39 阅读
  5. IntelliJ IDEA 插件开发中监听用户的保存事件

    2024-03-31 05:40:05       33 阅读
  6. c入门基础题(2)

    2024-03-31 05:40:05       37 阅读
  7. SQL注入(二)

    2024-03-31 05:40:05       43 阅读
  8. shell获取多个oracle库mysql库所有的表主键

    2024-03-31 05:40:05       40 阅读
  9. vue图片压缩

    2024-03-31 05:40:05       43 阅读
  10. RK3588平台开发系列讲解(开发环境搭建)

    2024-03-31 05:40:05       38 阅读
  11. springboot和spring的区别

    2024-03-31 05:40:05       35 阅读