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实例超出作用域时,数据会被清理
}