Rust datatypes
Rust does not use null, instead is uses Option
and Result
.
Documentation
primitives https://doc.rust-lang.org/std/#primitives
Literals
General
'a' // char "abc" // string (immutable) 1234 // i32 3.14 // f32 true/false // boolNumeric Representations
1_000 // == 1000 1.000_000 // == 1.000000 0xff // hex Oo644 // octal 0b1111_0000 // binary b'A' // byte (u8)Type Suffixes
1u8 // '1' as a u8 1i64 // '1' as a i64
Primitives
Text
str
- immutable
- size-known at compile-time
https://doc.rust-lang.org/std/primitive.str.html
let name: &str = "vaderd"; // assign string let mut user = String::new(); // utf8 string // type casting 'string' to 'i8' let num: i8 = "123" .parse() .unwrap();Some Useful Methods
"abc".len() // 3 number of bytes used "abc".ends_with("bc") // true if ends withchar
chars refer to a single character, and it's literals use single-quotes.
chars use 4-bytes in memory; they can store multibyte characters.https://doc.rust-lang.org/std/primitive.char.html
let foo: char = 'a';String
String types are strings with a string-size that is unknown at compile-time.
let mut mystr = String::from("foo") mystr.push("bar!"); // foobar!Numbers
implied type let var = 12;
assigned type let var: i8 = 12;
type suffix let var = 12i8;
int
- signed integers range is split in two, can be positive/negative
- unsigned integers are positive, and use all available bits
- use radix to calculate max size that can be accomodated with b bits
// signed integers, by bit-size i8 // -128..127 i16 // -32768..32767 i32 // -2147483648..2147483647 i64 // ... i128 isize // your CPU wordsize (ex. i32 or i64) // unsigned integers, by bit-size u8 // 0..255 u16 // 0..65535 u36 // 0..4294967295 u64 // ... u128 usize // your CPU wordsize (ex. u32 or u64)float
f32 f64bool
true false fn foo(b: bool) { ... }
Collections
tuples
- heterogenous
- non-resizable
- not stored in contiguous memory
- support nesting
https://doc.rust-lang.org/std/primitive.tuple.html#
let var: (i8, char, u32) = (5, 'a', 300); var = (1, "two", 3.14) var.0 // item at index 1arrays
- homogenous
- non-resizable
- stored in contiguous memory
https://doc.rust-lang.org/std/primitive.array.html
// initialization let var: [i32; 4] = [1, 2, 3, 4]; // declare an array of 4x 32-bit integers let var: [i32; 4] = [100; 4]; // initialize all 4x ints as 100 // methods var[0] // 1 var.len() // 4 // slices let foo = &var[1..2]; // [2, 3] println!("{}", foo[0]); // 2slices
slices are a subsection of an array
let var: [i8; 4] = [1, 2, 3, 4]; let first_two = &var[0..1]; // [1, 2] let first_two = &var[..1]; // [1, 2] println!("{}", foo[0]); // 2 fn foo(s: &[i32]) { ... } // borrows slice of an i32 array fn foo(s: String) -> &str { ... } // returns slice of String fn foo(nums: &[usize; 10]) -> &[usize] // returns slice of array (slice indexes always usize)vectors
vectors are essentially resizable arrays.
- homogenous
- resizable
- stored in contiguous memory
https://doc.rust-lang.org/std/vec/index.html
let v: Vec<i32> = Vec::new(); let v = vec![1, 2, 3, 4, 5];structs
Struct is either entirely mutable, or entirely immutable.
You cannot make some fields mutable and others not.Structs can contain references to objects owned by others.
Regular Structs
struct Point { x: u8, y: u8 } let p: Point = Point { x: 5, y: 10 }; // assignment println!("point({}, {})", p.x, p.y); // access fields with '.'Structs have syntactic sugar so that you can reuse parameters for assignment.
struct Coord { x: u8, y: u8, z: u8 }; fn build_coord_at_x0(x: u8, y: u8) { Coord{ x: 0, y, z } // bind `y`, `z` values from matching params }There is also syntactic sugar for creating a struct from another of the same type,
only replacing select values.struct Coord { x: u8, y: u8, z: u8 }; let p1 = Coord{x: 1, y: 2, z: 3}; let p2 = Coord{x: 5, ..p1}; // reuse fields from `p1` for all values except `x`Tuple Structs
struct Color(i8, i8, i8); // declaration let c: Color = Color(100, 150, 200); // instantiation c.1 = 200; // assignment (uses `.` index)Unit Structs
Unit structs have no value, they're just a type.
struct Centimeters; let cm = Centimeters;General
TODO:
not sure this really belongs here..
Debug trait
#[derive(Debug)] struct Point{x: i8, y: i8} let p = Point{x: 1, y: 2}; println!("{:?}", p); // print all fields on struct println!("{:#?}", p); // pretty-print struct dbg!(p) // prints the file, lineno, expression, and result
Pointers
Pointers
Function Pointers
References
Other
Enums
enum TaskStatus { Blocked, Ready, Started, Finished, } TaskStatus::ReadyYou can also store complex information in an enum,
encoding additional information with each possible enum value.enum Event { KeyPress(char), // like tuple-struct Click { x: i32, y: i32 }, // like c-structs Blue = 0x0000ff, // assign value } Event::KeyPress('j') Event::Click{x: 100, y: 900}Scoping with
use
use TaskStatus::*; let foo = Blocked; use TaskStatus::{Blocked, Ready}; let foo = Blocked; let bar = Started; // raises error, since not in scopeOption
The Option type (enum) stands in for
null
in rust.
It is commonly used withmatch
to extract the values.
It's methods are added to the prelude scope, so they are accessible without the namespace.https://doc.rust-lang.org/std/option/enum.Option.html
let val = Some("foo"); // `Option` instance, with value present let val = None; // `Option` instance, standin for null match val { Some(x) => println!("value was assigned"), // `x` here refers to whatever value is held by `Some` None => println!("value was not assigned"), }Result
Results are chainable enums with success/failure values.