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

1.控制流

rust 复制代码
//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);
    }

控制权

rust 复制代码
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.引用

rust 复制代码
//引用: 用法&,
//让我们创建一个指向值的应用,但是并不拥有它,因为不拥有这个值,所以,当引用离开其值指向的作用域后也不会被丢弃
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

rust 复制代码
//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
rust 复制代码
fn main() {
    let text: String = "Hello CSDN".to_string();
    // 将字符串移动到堆上 
    let box_text: Box<String> = Box::new(text);
    // 此时原text已失效,因为所有权已经转移给box_text
    println!("{}", box_text);
}
Rc
rust 复制代码
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实例超出作用域时,数据会被清理
}
相关推荐
2401_857622662 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589362 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰3 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
ChinaDragonDreamer3 小时前
Kotlin:2.0.20 的新特性
android·开发语言·kotlin
IT良3 小时前
c#增删改查 (数据操作的基础)
开发语言·c#
哎呦没4 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
Kalika0-04 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
_.Switch4 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
代码雕刻家4 小时前
课设实验-数据结构-单链表-文教文化用品品牌
c语言·开发语言·数据结构
一个闪现必杀技4 小时前
Python入门--函数
开发语言·python·青少年编程·pycharm