163 lines
2.6 KiB
Plaintext
163 lines
2.6 KiB
Plaintext
why printf is a macro
|
||
|
||
println works like printf
|
||
"{}" placeholders are subed with vars
|
||
|
||
so
|
||
|
||
printlin takes a variable number of args
|
||
rust functions don't support overloading, or take variable number of arguments.
|
||
|
||
macros can generate the functions with the number of called arguments
|
||
|
||
|
||
the collatz conjecture
|
||
|
||
rust infers types
|
||
print macro doesn't add \n!!!!
|
||
|
||
print/ln also can put var inside the "{}" string interpolation ftw!
|
||
|
||
doc: std.rs/
|
||
|
||
&thing
|
||
|
||
say: ref-thing
|
||
|
||
defining var without a value is uninitialized
|
||
access is an error
|
||
|
||
use default value:
|
||
|
||
let var = bool::default();
|
||
|
||
arrays! [T; N]
|
||
[20, 30, 40]
|
||
[0; 3] // three elements, all elements are 0
|
||
|
||
fixed contiguous chunk of memory
|
||
same type
|
||
|
||
slices!
|
||
variable contiguous chunk of memory
|
||
same type
|
||
|
||
&[T]
|
||
&array[0..5]
|
||
|
||
tuples!
|
||
fixed length, different types
|
||
|
||
let t = (7, true);
|
||
|
||
empty tuple: ()
|
||
called: unit
|
||
|
||
|
||
dot syntax
|
||
|
||
t.0;
|
||
t.1;
|
||
|
||
|
||
debug print
|
||
|
||
"{:?}" // use debug representation
|
||
|
||
|
||
references:
|
||
|
||
let mut x = 10;
|
||
let ref_x: &mut i32 = &mut x;
|
||
let ref_x = &mut x; // same thing
|
||
|
||
*ref_x = 20;
|
||
|
||
|
||
let a = [10, 20, 30, 40, 50];
|
||
println!("a: {a:$?}");
|
||
let s: &[i32] = &a[2..4];
|
||
println!("a: {a:$?}");
|
||
|
||
mutability xor sharability
|
||
|
||
String vs str (also a dozen more)
|
||
|
||
two core types:
|
||
|
||
&str (ref str) borrowed utf-8 chunks of data
|
||
so you can't append
|
||
|
||
String (part of std)
|
||
you want to own your string data, and be able to resize
|
||
|
||
vec dynamic array you can push and pop
|
||
|
||
range syntax:
|
||
for i in 1..=n { // include the last element
|
||
for i in 1..n { // up to the last element
|
||
|
||
}
|
||
|
||
|
||
match is kinda like switch:
|
||
|
||
match (thing, anotther thing) {
|
||
(true, true) => res,
|
||
(true, false) => res2,
|
||
_ => default case,
|
||
}
|
||
|
||
match is exhaustive by compiler directive!
|
||
|
||
|
||
|
||
last expression returns a value
|
||
|
||
arrow syntax to define return type of function
|
||
idiomatic return is to leave out return keyword and semicolon
|
||
|
||
"function returns unit" means the function doesn't return anything
|
||
|
||
default return is unit
|
||
|
||
docs.rs // docs for crate
|
||
rustdoc
|
||
|
||
|
||
methods!
|
||
|
||
functions associated with a particular type
|
||
|
||
struct Rectangle {}
|
||
|
||
impl Rectangle {
|
||
fn area(&self) -> u32 { //first arg is always either
|
||
// self
|
||
// &self
|
||
// &mut self
|
||
}
|
||
}
|
||
|
||
borrow completes at the end of block - easy mode
|
||
|
||
the compiler will put something out of scope when it's not used anymore
|
||
|
||
functions:
|
||
no default args
|
||
no function overloading
|
||
function parameter can be generic
|
||
|
||
available on line: comprehensive rust
|
||
|
||
go/comprehensive-rust-material
|
||
|
||
type conversions x as i16 etc.
|
||
|
||
traits!
|
||
type conversions in a generic way
|
||
x.into() will do the type conversion for you, if valid and lossless
|
||
|
||
|
||
|