$ curl https://sh.rustup.rs -sSf | sh
$ source $HOME/.cargo/env
$ rustc --version
$ cargo --version
$ rustup update
$ rustup self uninstall
$ rustup doc
$ mkdir hello_world
$ cd hello_world
$ touch main.ts
Filename: main.ts
fn main() {
println!("Hello, world!");
}
$ rustc main.ts
$ ./main
$ cargo new hello_cargo
$ cd hello_cargo
Filename: src/main.rs
fn main() {
println!("Hello, world!");
}
$ cargo build
Compiling hello_cargo v0.1.0 (/Users/lihzhang/Documents/rust-learn/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 1.74s
$ ./target/debug/hello_cargo
Hello, Cargo!
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.05s
Running `target/debug/hello_cargo`
Hello, Cargo!
$ cargo check
Checking hello_cargo v0.1.0 (/Users/lihzhang/Documents/rust-learn/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.18s
$ cargo build --release
Compiling hello_cargo v0.1.0 (/Users/lihzhang/Documents/rust-learn/hello_cargo)
Finished release [optimized] target(s) in 0.36s
[dependencies]
rand = "0.3.14"
Note:
0.3.14
is shorthand for^0.3.14
.
$ cargo build
Updating crates.io index
Compiling libc v0.2.50
Compiling rand v0.4.6
Compiling rand v0.3.23
Compiling guessing_game v0.1.0 (/Users/lihzhang/Documents/rust-learn/guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 14.13s
Note:
Cargo.lock
ensures reproducible builds in the future.
$ cargo update
Updating crates.io index
Filename: src/main.rs
use std::cmp::Ordering;
use std::io;
use rand::Rng;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1, 101);
loop {
println!("Please input your guess.");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("You guessed: {}", guess);
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
Variables, functions, structs, lots of things, all of these things need identifiers, which can be:
either:
- The first character is a letter.
- The remaining characters are alphanumeric or
_
.
or:
- The first character is
_
. - The identifier is more than one character.
_
alone is not an identifier. - The remaining characters are alphanumeric or
_
.
Identifiers cannot be keywords, unless use a “raw identifier”. Raw identifiers start with r#
:
let r#fn = "this variable is named 'fn' even though that's a keyword";
// call a function named 'match'
r#match();
let max_score = 0;
let last_name = "Lee";
let x = 5;
// error[E0384]: cannot assign twice to immutable variable `x`
x = 6;
let mut x = 5;
x = 6;
- Constants are always immutable.
- Constants use
const
instead oflet
. - Constants can be declared in any scope.
- Constants cannot be set at runtime.
const MAX_POINTS: u32 = 100_000;
let x = " ";
let x = x.len();
- Scalar Types
- Integer Types
- Floating-Point Types
f64
let x = 3.0;
let x = 1.0f64
let x: f64 = 1.0
f32
let x = 1.0f32
let x: f32 = 1.0
- The Boolean Type
bool
false
true
- The Character Type
char
'汉'
- Compound Types
- Two Primitive Compound Types
- The Tuple Type
- The Array Type
- Two Primitive Compound Types
Length | Signed | Unsigned |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
64-bit | i128 | u128 |
arch | isize | usize |
Number literals | Example |
---|---|
Decimal | 98_222 |
Hex | 0xff |
Octal | 0o77 |
Binary | 0b1111_0000 |
Byte(u8 only) |
b'A' |
let x = 32; // i32
let a: u32 = 16;
let b = 32i8;
let c = b'A'; // `u8` only
let tup: (i32, f64, u8) = (500, 6.4, 1);
let tup: (i32,) = (500,);
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
let tup = (500, 6.4, 1);
let (x, _, _) = tup;
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
let a: [i32; 5] = [1, 2, 3, 4, 5];
let a = [1, 2, 3, 4, 5];
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
- Cannot declare variables in
mod
level block. - Blocks always evaluate to the last expression:
- statement blocks evaluate to
()
, the empty tuple. - expression blocks evaluate to non-
()
. - loop blocks are supposed to evaluate to
()
due to uncertainty of how the loop terminated, butloop
blocks can break with a value. for
loop blocks must evaluate to()
.
- statement blocks evaluate to
- Blocks can terminate the nearst containing
fn
with thereturn
statement. - Blocks can break out of the nearst containing
loop
with thebreak
statement.
- All expressions except the last or block statements in a block should end with
;
. - If the last expression evaluates to
()
, it should end with;
too. - Block statements are those evaluating to
()
. - If an exprssion evaluates to
()
, it should not be assigned to a variable. - Expressions ending with
;
evaluate to()
.
- Use snake case naming convention.
- Must declare parameters type if have any.
- Need to explicitly declare return type unless
()
. - Always have a return value.
fn main() {
println!("{}", abs({ 1 + 3 } * 4)); // 16
println!("{}", abs(-4)); // 4
}
fn abs(x: i32) -> i32 {
opp(if x >= 0 {
return x;
} else {
x
})
}
fn opp(x: i32) -> i32 {
{
{
{
-x
}
}
}
}
There is only one style comment.
// So we’re doing something complicated here, long enough that we need
// multiple lines of comments to do it! Whew! Hopefully, this comment will
// explain what’s going on.
if
blocks are expressions.if
condition must evaluate tobool
type.- parentheses around
if
condition are omitted.
let number = 6;
if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
let condition = true;
let number = if condition {
5
} else {
6
};
loop {
println!("again!");
}
Unlike while
and for
mentioned below can be terminated both by condition turning into false
and by break
statement, loop
can only be terminated by break
statement, so a value can be returned from loops:
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
let mut number = 3;
while number != 0 {
println!("{}!", number);
number = number - 1;
}
let a = [10, 20, 30, 40, 50];
for element in &a {
println!("the value is: {}", element);
}