自学rust笔记 (2) 所有权引用和指针

133 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

所有权内存分配

字符串字面值 let s = "hello"

字面值不能被修改 String 类型可以被修改,需要在hap 上分配内存

rust 中变量走出作用域 调用drop方法

值的移动 move

let x = 5;
let y =x;

xy都是基础类型,xy都被压入栈中

let s1 = String::from("hello");
let s2 = s1;

此时 s1赋值给s2是s1被move ,s1 将不能被使用

这样避免了二次释放

rust 同样有深拷贝,只是针对 heap上的对象

let s1 = String::from("hello");
let s2 = s1.clone();

栈上数据都实现了 copy trait 所以x在之前的例子一直有效

标量类型都是实现了copy的,元组里面如果都是标量的话他也是可以copy的

函数的所有权

fn main() { 
  let s1 = gives_ownership(); // gives_ownership 将返回值 
  // 转移给 s1 
  let s2 = String::from("hello"); // s2 进入作用域 
  let s3 = takes_and_gives_back(s2); // s2 被移动到 
  // takes_and_gives_back 中, 
  // 它也将返回值移给 s3 
  } // 这里, s3 移出作用域并被丢弃。s2 也移出作用域,但已被移走, 
  // 所以什么也不会发生。s1 离开作用域并被丢弃 
  fn gives_ownership() -> String { // gives_ownership 会将 
  // 返回值移动给 
  // 调用它的函数 
  let some_string = String::from("yours"); // some_string 进入作用域. 
  some_string 
  // 返回 some_string 
  // 并移出给调用的函数 
  // } 
  // takes_and_gives_back 将传入字符串并返回该值 
  fn takes_and_gives_back(a_string: String) -> String { 
  // a_string 进入作用域 
  a_string 
  // 返回 a_string 并移出给调用的函数 
  }
  • 变量传给方法就跟赋值给变量是一样的会发生移动或者复制
  • 返回值同样会发生所有权转移
  • 一个值赋值给其他变量的时候发生移动
  • heap 离开作用域会被 drop 清理

引用和借用

fn main() { 
   let s1 = String::from("hello"); 
   let len = calculate_length(&s1); 
   println!("The length of '{}' is {}.", s1, len); 
} 
fn calculate_length(s: &String) -> usize {
   s.len() 
   }

为了避免所有权转移,引用类似指针 跟创建默认变量一样,创建引用是不能修改操作的

fn main() { 
 let s = String::from("hello"); 
 change(&s); 
} 
fn change(some_string: &String) {            some_string.push_str(", world"); 
}

和let mut 相同增加 mut 可以改成可变引用

fn main() { 
  let mut s = String::from("hello");
  change(&mut s); } 
fn change(some_string: &mut String) {
  some_string.push_str(", world"); 
}

但是不允许同时创建两个相同的引用的,避免数据竞争 不能同时拥有一个可变引用一个不可变引用 可以同时拥有两个不可变引用 引用的值必须还在作用域之内