内容整理自:https://doc.rust-lang.org/book/title-page.html
Chapter 3:Common Programming Concepts
Variables and Mutability
- by default variables are immutable
- mut:
let mut x = 5;
- Differences Between Variables and Constants
- let(Variables) vs const(Constants) to declare
- Constants can be declared in any scope, including the global scope
- Constants maybe set to a constant expression, not function call result or any expression need to be computed in runtime.
- Define a constant
const MAX_POINTS: u32 = 100_000;
Use underscore between words
Data Types
- Rust is a static type lang, it must know all data types at compile time.
- 2 data types
- Scalar
- Compound
- Scalar types
- four primary types:
- Integer
- Float-Point Number
- Boolean
- Character
- Integer
- signed and unsigned
- i8, i16, i32, i64, i128, isize; u8, u16, u32, u64, u128, usize
- Integer Overflow
- debug mode: throw panic! error
- release mode: complement wrapping: 256 becomes 0, 257 becomes 1
- Floating-Point
- f32 and f64(default)
- f32: single-precision
- f64: double-precision
- four primary types:
fn main() {
let x = 2.0; // f64
let y: 32 = 3.0; // f32
}
* Boolean
* `let f = true;` or `let f: bool = true;`
* one byte in size
* Character
* `let c = ‘z’`
* use single quotes (string use double quotes)
* 4 bytes in size
* Unicode Scalar Value
* range: U+0000 to U+D7FF and U+E000 to U+10FFFF
- Compund Types
- can group multiple values into one type
- 2 types
- Tuple
- Array
- Tuple
- group different types into one compound
- fixed length, can not change after declared
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
}
* can use period(.) to access value
fn main() {
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
}
* Arrary
* must the same type
* have a **fixed** length
fn main() {
let a = [1, 2, 3, 4, 5];
let b: [i32; 5] = [1, 2, 3, 4, 5];
}
Functions
- main function: the entry point
- fn keyword
- snake case: lowercase + underscore
- must declare the type of each parameter
- expressions return a value, without a semicolon at the end
fn main() {
let x = 5;
let y = {
let x = 3;
x + 1
};
println!("The value of y is: {}", y);
}
- y evaluates to 4
- With return values
fn five() -> i32 {
5
}
Comments
// hello, world
Control Flow
- if
- the condition must be a bool
- can use if in a let statement
fn main() {
let condition = true;
let number = if condition {
5
} else {
6
};
println!("The value of number is: {}", number);
}
- Loops
- loop, while, for
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
}
fn main() {
let a = [10, 20, 30, 40, 50];
let mut index = 0;
while index < 5 {
println!("the value is: {}", a[index]);
index += 1;
}
}
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("the value is: {}", element);
}
}
Chapter 4: Understanding Ownership
- rust’s most unique feature
- make memory safety
- without needing a garage collector
what is ownership
- rules
- each value has a variable called its owner
- only one owner at a time
- owner goes out of scope, the value will be dropped
References and Borrowing
- & -> reference
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()
}
- create a reference that refers to the value of s1 but does not own it
- borrowing: having references as function parameters
- you can not modify a borrowed value
- Mutable References
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
- can not borrow twice, error:
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);
- rules of references:
- At any given time, you can have either one mutable reference or any number of immutable references.
- References must always be valid.
The Slice Type
- string slice: reference to part of a string
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
- String Literals Are Slices: it’s a slice pointing to that specific point of the binary
- “string slice” is written as &str
fn main() {
let my_string = String::from("hello world");
// first_word works on slices of `String`s
let word = first_word(&my_string[..]);
let my_string_literal = "hello world";
// first_word works on slices of string literals
let word = first_word(&my_string_literal[..]);
// Because string literals *are* string slices already,
// this works too, without the slice syntax!
let word = first_word(my_string_literal);
}
- Other Slices
let a = [1, 2, 3, 4, 5];
let slice = &a[1..3];