Run src.main.rs or src.lib
cargo run
add my_file.rs in examples/my_file.rs
cargo run --example my_file
cargo new todo --lib
Create a file in src/bin/file.rs Run it using
cargo run --bin file
Immutable by default
let x = 5;
x = 6; // <-- will throw error
let mut x = 5;
x = 6; // ok
const MYCONST: u32 = 60 * 60;
let x = 5; // 5
let x = 5 + 33; // 6
{
let x = x * 2; // 12
}
let tup: (i32, f64, u8) = (500, 6.2, 1);
let a: [i32; 5] = [1,2,3,4,5];
let a: [3; 5]; // [3,3,3,3,3]
let v: Vec<i32> = Vec::new();
// same as
let v = vec![1, 2, 3];
let mut v = Vec::new();
v.push(5);
{
let v = vec![1, 2, 3, 4];
// do stuff with v
} // < v goes out of scope and is freed here
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2]; // access 3rd element
match v.get(2) { // access 3rd element
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}
enum Work {
Civilian,
Soldier,
}
use a matcher expression (switch like)
// Automatically `use` each name inside `Work`.
use crate::Work::*;
match status {
// Note the lack of scoping because of the explicit `use` above.
Rich => println!("The rich have lots of money!"),
Poor => println!("The poor have no money..."),
}
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
if number < 10 {
//...
} else if number > 12 {
//...
} else {
//...
}
let number = if condition {5} else {6};
when we see a struct with a lifetime type-parameter it refers to the lifetimes of the references owned by this struct and nothing else.
pub struct Project<'a> {
project_repository: &'a ProjectRepository,
pub title: String,
}
impl<'a> Project<'a> {
pub fn create(project_repository: &'a ProjectRepository, title: String) -> Self {
Self {
title,
project_repository,
}
}
}
for i in 0..10 {
//...
}
while n < 10 {
//...
}
loop {
if remain == 9 {
break;
}
}
// break, continue keyworks works
pub mod mymodule {
pub fn my_function1() {} // public accessible function
fn my_function1() {} // private function
}
InnerAttribute : # ! [ Attr ]
OuterAttribute : # [ Attr ]
// General metadata applied to the enclosing module or crate.
#![crate_type = "lib"]
// A function marked as a unit test
#[test]
fn test_foo() { /* ... */}
type Point = (u8, u8);
let p: Point = (41, 68);
A trait describes an abstract interface that types can implement.
trait NonDispatchable {
// Non-methods cannot be dispatched.
fn foo() where Self: Sized {}
// Self type isn't known until runtime.
fn returns(&self) -> Self where Self: Sized;
// `other` may be a different concrete type of the receiver.
fn param(&self, other: Self) where Self: Sized {}
// Generics are not compatible with vtables.
fn typed<T>(&self, x: T) where Self: Sized {}
}
struct S;
impl NonDispatchable for S {
fn returns(&self) -> Self where Self: Sized { S }
}
let obj: Box<dyn NonDispatchable> = Box::new(S);
obj.returns(); // ERROR: cannot call with Self return
obj.param(S); // ERROR: cannot call with Self parameter
obj.typed(1); // ERROR: cannot call with generic type
First option add copy or clone trait
#[derive(Copy, Clone)]
struct Point {
x: i32,
y: i32,
}
You can also implement Copy and Clone manually:
struct MyStruct;
impl Copy for MyStruct { }
impl Clone for MyStruct {
fn clone(&self) -> MyStruct {
*self
}
}
Format a string:
format!("{0}:{1}", self.app.url, self.app.port)
pub fn from_file(path: &'static str) -> Self {
let config = fs::read_to_string(path).unwrap();
serde_json::from_str(&config).unwrap()
}
- Cell // A mutable memory location.
- RefCell // A mutable memory ref location.
- Arc // shares memory ref between thread
Call a function as parameter
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
f(arg) + f(arg)
}
cargo install systemfd cargo-watch
systemfd --no-pid -s http::PORT -- cargo watch -x run
install these extensions for a great experience
code --install-extension matklad.rust-analyzer
code --install-extension vadimcn.vscode-lldb