Rust datatypes: Difference between revisions

From wikinotes
Line 216: Line 216:
== structs ==
== structs ==
<blockquote>
<blockquote>
All struct fields are always mutable.
=== Regular Structs ===
=== Regular Structs ===
<blockquote>
<blockquote>

Revision as of 18:55, 7 February 2023

Documentation

primitives https://doc.rust-lang.org/std/#primitives

Literals

General

'a'        // char
"abc"      // string (immutable)
1234       // i32
3.14       // f32
true/false // bool

Numeric 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 with

char

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
f64

bool

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 1

arrays

  • 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]); // 2

slices

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

All struct fields are always mutable.

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);
let c: Color = Color(100, 150, 200);

Unit Structs

Unit structs have no value, they're just a type.

struct Centimeters;
let cm = Centimeters;

Pointers

Pointers

Function Pointers

References

Other

Enums

enum TaskStatus {
  Blocked,
  Ready,
  Started,
  Finished,
}

TaskStatus::Ready

You can also store complex information in a struct

enum Event {
  KeyPress(char),            // like tuple-struct
  Click { x: i32, y: i32 },  // like c-structs
  Blue = 0x0000ff,           // assign value
}

Event::KeyPress('j')

Scoping with use

use TaskStatus::*;
let foo = Blocked;

use TaskStatus::{Blocked, Ready};
let foo = Blocked;
let bar = Started;  // raises error, since not in scope

Result

Results are chainable enums with success/failure values.