赞
踩
//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!"); }
//引用: 用法&, //让我们创建一个指向值的应用,但是并不拥有它,因为不拥有这个值,所以,当引用离开其值指向的作用域后也不会被丢弃 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); }
//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 }
fn main() {
let text: String = "Hello CSDN".to_string();
// 将字符串移动到堆上
let box_text: Box<String> = Box::new(text);
// 此时原text已失效,因为所有权已经转移给box_text
println!("{}", box_text);
}
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实例超出作用域时,数据会被清理
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。