RustBrock/data_types.md
2025-01-02 14:12:46 -07:00

7.4 KiB

Data Types

Constants

constants can be delared anywhere, convension to use all caps in const need const keyword, not always eval at compile time variables can only be assigned once (needs mut to assign more than once (need to be same type))

const SECONDS_PER_HOUR: i32 = 60 * 60;

Variables

variables are immuatable by default variables can be inferred but sometimes needs explicit typing

    let foo = 5;

need to add mut keyword to enable rewriting, generally avoid unless actually used

    let mut bar = 6;

SHADOWING

Cannot have mutable shadows

allows for reuse of namespace instead of spaces_str and spaces_num

    let spaces = " _ _ ";
    let spaces = spaces.len();
    // will output 5 instead of " _ _ " beacuse that is how long it is
    // the shadow of spaces (first) wont be printed until the overshadow of spaces goes out of scope
    println!("{spaces}"); // output: 5

not allowed shadow

    let mut spaces = " _ _ ";
    spaces = spaces.len();

cannot change type of variable once declared

Primitive Data Types

Scalars

Integers

u is for usigned integers i is for signed integers

number indicated how many bits it takes in memory

    let z: i8;      // takes up 8 bits, can store values from -128 to 127
    let c: i16;     // takes up 16 bits
    let d: i32;     // takes up 32 bits (default for integers)
    let e: i64;     // takes up 64 bits
    let f: i128;    // takes up 128 bits
    let g: isize;   // takes up x bits, depends on the system's architecture/cpu

    let h: u8;      // takes up 8 bits, unsigned version (only positive)
                    // can store values from 0 to 255

Integer Overflow

will reset to the lowest value ie i8 129 -> -126

    let example_over_flow: i8 = 129;

behavor only in production mode dev mode will cause a panic and error out/tell you

Floats

better to use double point due to modern cpus where there is not much difference in speed

Single Point Float

takes up 32 bits

    let a: f32 = 4.0;

Double Point Float

takes up 64 bits

    let b: f64 = 2.01;

Integers Represented Differently

can represent values in hex, oct, bin or dec can hover with rust-analyzer extension to see value in dec

Dec with Reading Aid

value stored 1000 _ used to make easier to read

    let i = 1_000;
Hexidecimal

value stored 255

    let j = 0xff;
Octal

value stored 63

    let k = 0o77; 
Binary

value stored 13

    let l = 0b1101;
Bytes

u8 only value stored 0x41 or 65

    let m = b'A';

Numeric Operators / Basic Math

Numbers for reference

    let x: i16 = 8;
    let y: i16 = 5;

Addition

    let sum  = x + y; // result: 13

Subtraction

    let difference = x - y; //result: 3

Multiplication

    let product: i16;
    product = x * y;

Division

    let quotent = 45.1 / 54.2;
    let truncated = x / y; // results in 1 (always rounds down)

Remainder

    let remainder = x % y;

Booleans

must be explicity typed to true or false 0 or 1 not allowed even with let var: bool

    let n = false;
    let o = true;

Char

must use single quotes and not "" otherwise will be inferred as string literal is stored as Unicode Scalar Value allowing for emoji, japanse char and other languages not supported by ASCII takes 4 bytes in size or 32 bits

    let p = 'a';

Compound Types

multiple values into one type

Tuple

A general way of grouping multiple a number of values into one compound type types do not need to be the same in every position

    let tup: (i32, f64, u8) = (500, 6.4, 1);

The variable tup has values written to it at initialization but it is not requried, order does not matter similar to a struct in c

Vaules must be destructed out of a tuple to be accessed inidivually, can use a pattern matching to the tuple

 let (q, r, s) = tup;

This is called destructing becasue it breaks it into 3 parts

Can also be accessed with a .

INDEX STARTS AT 0

    let t = tup.0;  // t = 500
    let u = tup.1;  // u = 6.4
    let v = tup.2;  // v = 1

A Unit

This is a special value where a tuple has no values

    let w: () = ();

This represents an empty type or an empty return type

Expressions will implicitly return a unit if they dont return anything else

Array

A collection of multiple values Must have every value be the same type, cannot mix and match Arrays must be a fixed length at initialization useful when you want a set number of values or is static

Values are in [] and seperated by ,

    let xa = [1, 2, 3, 4, 5, 6];

Array located in stack same with above types

If you need your array/list to grow or shrink use a vector If unsure weather to use an Array or Vector pick a vector

Times where using an array is better

let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

Accessing items in an array

    let ya = xa[0]; //value is 1

Initializing an Array

    let za: [i32; 5];   // allows for 5 32 bit signed integers inside
    let aa = [i8; 6];   // allow for 6 8 bit signed integers inside

Invalid Array Elements

use std::io;
fn main() {
    let a = [1, 2, 3, 4, 5];

    // Input of a number
    println!("Please enter an array index.");
    let mut index = String::new();
    io::stdin()
        .read_line(&mut index)
        .expect("Failed to read line");

    // change into a integer
    let index: usize = index
        .trim()
        .parse()
        .expect("Index entered was not a number");

    // access elemetn in array
    let element = a[index];
    println!("The value of the element at index {index} is: {element}");
}

this program would compile with not problems for example inputting 7 into the program this would cause a runtime error the program would output an error because it didnt get to the final line println! before exiting it casue the program to exit before attempting to access the invalid space this is a form of safe memory management that rust name

Complex Data Type

String Literal

This is a string literal it is hardcoded into a program Always immutable Fast and efficient, stored on the stack, property of being immuatable not of any real value

    let s: &str = "hello";

String

This is a string that is stored on the heap, this can store data unkown (size, char, etc) to you at compile time Can be mutable, but must request space on the heap then return that memory to the heap, will be returned as soon as it is no longer valid (it calls the drop method from String) not as fast and efficient Example of a string being created form a string literal

    let ab:String = String::from("hello");

String concatinization example

    let mut s = String::from("hello");
    s.push_str(", world!"); // push_str() appends a literal to a String
    println!("{s}"); // This will print `hello, world!`