rust学习笔记之小练习:移动、生命周期、智能指针、多线程
移动
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); // vec1 has length 3 content `[22, 44, 66]`
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); // vec1 has length 4 content `[22, 44, 66, 88]`
// println!("{} has length {} content `{:?}`", "vec1", vec0.len(), vec0); // 编译报错
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
练习 2
fn main() {
let mut vec0 = Vec::new();
let mut vec1 = fill_vec(&mut vec0);
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0); // vec0 has 3 content `[22, 44, 66]`
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); // vec1 has 4 content `[22, 44, 66, 88]`
}
fn fill_vec(vec: &mut Vec<i32>) -> Vec<i32> {
vec.push(22);
vec.push(44);
vec.push(66);
vec.clone()
}
练习 3
fn main() {
let mut vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
练习 4
fn main() {
let mut vec1 = fill_vec();
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec() -> Vec<i32> {
let mut vec = Vec::new();
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
练习 5
fn main() {
let mut x = 100;
let y = &mut x;
*y += 100;
let z = &mut x;
*z += 1000;
assert_eq!(x, 1200);
let data = "Rust is great!".to_string();
get_char(&data);
string_uppercase(data);
}
fn get_char(data:&String) -> char {
data.chars().last().unwrap()
}
fn string_uppercase(mut data: String) {
data = data.to_uppercase();
println!("{}", data);
}
引用的生命周期
struct Book<'a> {
author: &'a str,
title: &'a str,
}
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is '{}'", result);
let name = String::from("Jill Smith");
let title = String::from("Fish Flying");
let book = Book { author: &name, title: &title };
println!("{} by {}", book.title, book.author);
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
智能指针
Box
#[derive(PartialEq, Debug)]
pub enum List {
Cons(i32, Box<List>),
Nil,
}
fn main() {
println!("This is an empty cons list: {:?}", create_empty_list());
println!("This is a non-empty cons list: {:?}",create_non_empty_list());
assert_eq!(List::Nil, create_empty_list());
assert_ne!(create_empty_list(), create_non_empty_list());
}
pub fn create_empty_list() -> List {
List::Nil
}
pub fn create_non_empty_list() -> List {
List::Cons(1, Box::new(List::Nil))
}
Rc
use std::rc::Rc;
#[derive(Debug)]
struct Sun {}
#[derive(Debug)]
enum Planet {
Mercury(Rc<Sun>),
Venus(Rc<Sun>),
Earth(Rc<Sun>),
Mars(Rc<Sun>),
Jupiter(Rc<Sun>),
Saturn(Rc<Sun>),
Uranus(Rc<Sun>),
Neptune(Rc<Sun>),
}
impl Planet {
fn details(&self) {
println!("Hi from {:?}!", self)
}
}
fn main() {
let sun = Rc::new(Sun {});
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
let mercury = Planet::Mercury(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
mercury.details();
let venus = Planet::Venus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
venus.details();
let earth = Planet::Earth(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
earth.details();
let mars = Planet::Mars(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
mars.details();
let jupiter = Planet::Jupiter(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
jupiter.details();
let saturn = Planet::Saturn(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
saturn.details();
let uranus = Planet::Uranus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details();
let neptune = Planet::Neptune(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details();
assert_eq!(Rc::strong_count(&sun), 9);
drop(neptune);
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
drop(uranus);
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
drop(saturn);
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
drop(jupiter);
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
drop(mars);
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
drop(earth);
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
drop(venus);
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
drop(mercury);
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
assert_eq!(Rc::strong_count(&sun), 1);
}
Arc
use std::sync::Arc;
use std::thread;
fn main() {
let numbers: Vec<_> = (0..100u32).collect();
let shared_numbers = Arc::new(numbers);
let mut joinhandles = Vec::new();
for offset in 0..8 {
let child_numbers = Arc::clone(&shared_numbers);
joinhandles.push(thread::spawn(move || {
let sum: u32 = child_numbers.iter().filter(|n| *n % 8 == offset).sum();
println!("Sum of offset {} is {}", offset, sum);
}));
}
for handle in joinhandles.into_iter() {
handle.join().unwrap();
}
}
Cow
Cow(Copy on Write)智能指针是一种写时克隆的智能指针,主要用于优化读多写少的场景。它通过延迟复制操作来提高性能,在需要修改数据时才进行实际的复制操作。
use std::borrow::Cow;
fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
for i in 0..input.len() {
let v = input[i];
if v < 0 {
input.to_mut()[i] = -v;
}
}
input
}
fn main() {
// 没有 clone 发生,因为 `input` 不需要被改变。
let slice = [0, 1, 2];
let mut input = Cow::from(&slice[..]);
match abs_all(&mut input) {
Cow::Borrowed(v) => println!("I borrowed the slice: {:?}", v),
_ => panic!("expected borrowed value"),
}
println!("{:?}",slice);
// 发生了 clone, 因为 `input` 需要被改变。
let slice = [-1, 0, 1];
let mut input = Cow::from(&slice[..]);
match abs_all(&mut input) {
Cow::Owned(v) => println!("I modified the slice and now own it: {:?}",v),
_ => panic!("expected owned value"),
}
println!("{:?}",slice);
// 没有 clone 发生,因为已经持有了 `input`。
let slice = vec![-1, 0, 1];
let mut input = Cow::from(slice);
match abs_all(&mut input) {
Cow::Owned(v) => println!("I own this slice: {:?}",v),
_ => panic!("expected borrowed value"),
}
}
多线程
use std::thread;
use std::time::Duration;
fn main() {
let mut handles = vec![];
for i in 0..10 {
handles.push(thread::spawn(move || {
thread::sleep(Duration::from_millis(250));
println!("thread {} is complete", i);
}));
}
let mut completed_threads = 0;
for handle in handles {
handle.join().unwrap();
completed_threads += 1;
}
if completed_threads != 10 {
panic!("Oh no! All the spawned threads did not finish!");
}
}
练习 2
use std::sync::{Arc,Mutex};
use std::thread;
use std::time::Duration;
struct JobStatus {
jobs_completed: u32,
}
fn main() {
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let mut handles = vec![];
for _ in 0..10 {
let status_shared = Arc::clone(&status);
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250));
let mut js = status_shared.lock().unwrap();
js.jobs_completed += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
let js = status.lock().unwrap();
println!("jobs completed {}", js.jobs_completed);
}
}
练习 3
use std::sync::mpsc;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
struct Queue {
length: u32,
first_half: Vec<u32>,
second_half: Vec<u32>,
}
impl Queue {
fn new() -> Self {
Queue {
length: 10,
first_half: vec![1, 2, 3, 4, 5],
second_half: vec![6, 7, 8, 9, 10],
}
}
}
fn send_tx(q: Queue, tx: mpsc::Sender<u32>){
let qc = Arc::new(q);
let qc1 = Arc::clone(&qc);
let tx1=tx.clone();
thread::spawn(move || {
for val in &qc1.first_half {
println!("sending {:?}", val);
tx1.send(*val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
thread::spawn(move || {
for val in &qc.second_half {
println!("sending {:?}", val);
tx.send(*val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
}
fn main() {
let (tx, rx) = mpsc::channel();
let queue = Queue::new();
let queue_length = queue.length;
send_tx(queue, tx);
let mut total_received: u32 = 0;
for received in rx {
println!("Got: {}", received);
total_received += 1;
}
println!("total numbers received: {}", total_received);
assert_eq!(total_received, queue_length);
}
浙公网安备 33010602011771号