Rust编程语言入门教程课程笔记
参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community)
fn main() {
//Vector
let mut v: Vec<i32> = Vec::new();//new empty vector
v.push(1);
let v2 = &v[0];//immutable borrow
//v.push(2);//mutable borrow
//cannot borrow `v` as mutable because it is also borrowed as immutable
//because v.push will cause the vector to reallocate and invalidate the reference
//so v2 may be pointing to deallocated memory
println!("The first element is: {}", v2);
let mut u = vec![1, 2, 3];//new vector with values
println!("u[0] = {:?}", u[0]);//access element with index
println!("u[1] = {:?}", u.get(1));//access element with get()
match u.get(1) {
Some(second) => println!("The second element is {}", second),
None => println!("There is no second element."),
}
u.insert(0, 0);//insert element at index
for i in &u {//immutable borrow
println!("{}", i);
}
for i in &mut u {//mutable borrow
*i += 50; //dereference i and add 50 to it
}
//using enum to store multiple types in a vector
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Float(10.12),
SpreadsheetCell::Text(String::from("blue")),
];
for i in &row {//for + match
match i {
SpreadsheetCell::Int(i) => println!("Int: {}", i),
SpreadsheetCell::Float(f) => println!("Float: {}", f),
SpreadsheetCell::Text(s) => println!("Text: {}", s),
}
}
//String
let mut s = String::new();//new empty string
println!("{}", s);
let data = "initial contents 0";//new string from string literal
s = data.to_string();//new string from string literal
println!("{}", s);
s = "initial contents 1".to_string();//new string from string literal
println!("{}", s);
s = String::from("initial contents 2");//new string from string literal
println!("{}", s);
s.push_str("bar");//append string literal
println!("{}", s);
s.push('l');//append char
println!("{}", s);
//concatenation
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2;//s1 has been moved here and can no longer be used
println!("{}", s3);
//format! macro
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s4 = format!("{}-{}-{}", s1, s2, s3);//s1, s2, s3 not moved
println!("{}", s1);
println!("{}", s2);
println!("{}", s3);
println!("{}", s4);
//indexing
let s1 = String::from("hello");
//let h = s1[0];//cannot index into a String
let h = &s1[0..1];//indexing with range
println!("{}", h);
//length
let len = String::from("Hola").len();//length in bytes
println!("{}", len);
let len = String::from("Здравствуйте").len();//length in bytes
println!("{}", len);
let len = String::from("Здравствуйте").chars().count();//length in chars
println!("{}", len);
//iteration
for c in "नमस्ते".chars() {
println!("{}", c);
}
for b in "नमस्ते".bytes() {
println!("{}", b);
}
//Hash Map
//HashMap stores a mapping of keys of type K to values of type V
use std::collections::HashMap;//hashmap is not in the prelude
let mut scores = HashMap::new();//new empty HashMap
scores.insert(String::from("Blue"), 10);//insert key-value pair
scores.insert(String::from("Yellow"), 50);//insert key-value pair
println!("{:?}", scores);
//collecting into a hashmap
let teams = vec![String::from("Blue"), String::from("Yellow")];//new vector
let initial_scores = vec![10, 50];//new vector
let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();//collect into hashmap
//HashMap<_,_> type annotation is needed because collect can collect into many different data structures
//zip() creates a vector of tuples
println!("{:?}", scores);
//ownership
let field_name = String::from("Favorite color");
let field_value = String::from("Blue");
let mut map = HashMap::new();//new empty hashmap
//map.insert(field_name, field_value);//field_name and field_value are moved into map
//println!("{}", field_name);//field_name and field_value are moved into map
map.insert(&field_name, &field_value);//field_name and field_value are borrowed
println!("{}", field_name);//field_name and field_value are borrowed
//accessing values in a hashmap
let team_name = String::from("Blue");
let score = scores.get(&team_name);//get() returns an Option<&V>
match score {
Some(s) => println!("{}", s),
None => println!("No score"),
}
//iterating over a hashmap
for (key, value) in &scores {
println!("{}: {}", key, value);
}
//updating a hashmap
//overwriting a value
let mut scores = HashMap::new();//new empty hashmap
scores.insert(String::from("Blue"), 10);//insert key-value pair
scores.insert(String::from("Blue"), 25);//overwrite value
println!("{:?}", scores);
//only inserting a value if the key has no value
scores.entry(String::from("Yellow"));//insert key-value pair if key has no value
scores.entry(String::from("Yellow")).or_insert(50);//insert key-value pair if key has no value
scores.entry(String::from("Blue")).or_insert(50);//do not insert key-value pair if key has value
println!("{:?}", scores);
//updating a value based on the old value
let text = "hello world wonderful world";
let mut map = HashMap::new();//new empty hashmap
for word in text.split_whitespace() {//split string into words
let count = map.entry(word).or_insert(0);//insert key-value pair if key has no value
*count += 1;//dereference count and increment it
}
println!("{:?}", map);
}