-
Couldn't load subscription status.
- Fork 2
Rust
Tomas Tulka edited this page Nov 28, 2024
·
20 revisions
- https://doc.rust-lang.org/reference/
- https://doc.rust-lang.org/book/
- https://doc.rust-lang.org/cargo/
- https://crates.io
fn main() {
println!("Hello, world!");
}cargo --version
cargo new hello
cargo new hello --lib
cargo check
cargo run
cargo run -- arg1 arg2
cargo build
cargo build --release
cargo update
cargo testmod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::deliver_order();
}
fn cook_order() {}
}use crate::front_of_house::hosting as host;
pub fn eat_at_restaurant() {
host::add_to_waitlist();
}use std::io;
...
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
let parsed_num: u32 = match input.trim().parse() {
Ok(num) => num,
Err(_) => 0,
};let x = 5;
let y = 10;
println!("x = {x} and y + 2 = {}", y + 2);// cargo run -- first second
let args: Vec<String> = env::args().collect();
let first = &args[1];
let second = &args[2];use std::fs;
let contents = fs::read_to_string(file_path)
.expect("Cannot read the file");use std::env;
let myvar = env::var("MYVAR").unwrap_or_else("default")#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {rect1:?}"); // or {:#?}
}fn main() {
let scale = 2;
let rect1 = Rectangle {
width: dbg!(30 * scale),
height: 50,
};
dbg!(&rect1);
}| Length | Signed | Unsigned |
|---|---|---|
| 8-bit | i8 | u8 |
| 16-bit | i16 | u16 |
| 32-bit | i32 | u32 |
| 64-bit | i64 | u64 |
| 128-bit | i128 | u128 |
| arch | isize | usize |
| Length | Signed |
|---|---|
| 32-bit | f32 |
| 64-bit | f64 |
let t = true;
let f: bool = false;let c = 'z';
let z: char = 'ℤ';
let heart_eyed_cat = '😻';
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup;
let five_hundred = tup.0;let a = [1, 2, 3, 4, 5];
let a: [i32; 5] = [1, 2, 3, 4, 5];
let a = [3; 5]; // [3, 3, 3, 3, 3]
let first = a[0];
let second = a[1];struct User {
active: bool,
email: String,
}
let mut user1 = User {
active: true,
email: String::from("a@example.com"),
};
user1.email = String::from("b@example.com");
let email = user1.email;
let user2 = User {
active: false,
email
}
let user3 = User {
active: false,
..user1
}struct Point(i32, i32, i32);
let origin = Point(0, 0, 0);struct AlwaysEqual;
let subject = AlwaysEqual;struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
let rect1 = Rectangle {
width: 30,
height: 50,
};
rect1.area()impl Rectangle {
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}type Kilometers = i32;// The never type that never returns
fn bar() -> ! {
...
}let mut x = 5;
x = 6;const PI_VALUE: f32 = 3.14;let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("x in the inner scope is: {x}"); // 12
}
println!("x is: {x}"); // 6fn main() {
let s = String::from("hello"); // s comes into scope
takes_ownership(s); // s's value moves into the function...
// ... and so is no longer valid here
let x = 5; // x comes into scope
makes_copy(x); // x would move into the function,
// but i32 is Copy, so it's okay to still
// use x afterward
} // Here, x goes out of scope, then s. But because s's value was moved, nothing
// special happens.
fn takes_ownership(some_string: String) { // some_string comes into scope
println!("{some_string}");
} // Here, some_string goes out of scope and `drop` is called. The backing
// memory is freed.
fn makes_copy(some_integer: i32) { // some_integer comes into scope
println!("{some_integer}");
} // Here, some_integer goes out of scope. Nothing special happens.&i32 // a reference
&'a i32 // a reference with an explicit lifetime
&'a mut i32 // a mutable reference with an explicit lifetimefn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}struct Excerpt<'a> {
part: &'a str,
}impl<'a> Excerpt<'a> {
fn level(&self) -> i32 {
3
}
}let s: &'static str = "I have a static lifetime.";fn main() {
let five = my_function(5);
}
fn my_function(x: i32) -> i32 {
println!("The value of x is: {x}");
x
}fn main() {
let s1 = String::from("hello");
let (s2, len) = calculate_length(s1);
println!("The length of '{s2}' is {len}.");
}
fn calculate_length(s: String) -> (String, usize) {
let length = s.len(); // len() returns the length of a String
(s, length)
}fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{s1}' is {len}.");
}
fn calculate_length(s: &String) -> usize {
s.len()
}fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}let mut s = String::from("hello");
let r1 = &s; // no problem
let r2 = &s; // no problem
println!("{r1} and {r2}");
// variables r1 and r2 will not be used after this point
let r3 = &mut s; // no problem
println!("{r3}");fn add_one_v1 (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x| { x + 1 };
let add_one_v4 = |x| x + 1 ;Closures:
let list = vec![1, 2, 3];
let only_borrows = || println!("From closure: {list:?}");
only_borrows();fn returns_closure() -> Box<dyn Fn(i32) -> i32> {
Box::new(|x| x + 1)
}Function pointers:
fn add_one(x: i32) -> i32 {
x + 1
}
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
f(arg) + f(arg)
}
let answer = do_twice(add_one, 5);let number = 6;
if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}let condition = true;
let number = if condition { 5 } else { 6 };loop {
...
continue;
...
break;
}let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};'first_loop: loop {
...
loop {
if ... {
break;
}
else {
break 'first_loop;
}
}
}while number > 0 {
number -= 1;
}let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {element}");
}for number in (1..4).rev() {
println!("{number}!"); // 3! 2! 1!
}let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {s1}, s2 = {s2}");let data: &str = "hello"; // string slice
let s: String = data.to_string(); // string boxlet mut s = String::from("he");
s.push_str("ll");
s.push('o');let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // note s1 has been moved here and can no longer be usedlet s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{s1}-{s2}-{s3}");let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];let s = String::from("abcde");
let slice = &s[3..len]; // de
let slice = &s[3..]; // de
let slice = &s[0..len]; // abcde
let slice = &s[..]; // abcdefn main() {
let s1 = String::from("s1");
let s2 = "s2";
print_slice(&s1);
print_slice(s2);
}
fn print_slice(s: &str) {
println!("slice: {s}");
}enum IpAddrKind {
V4,
V6,
}
let four = IpAddrKind::V4;
fn route(ip_kind: IpAddrKind) {}enum IpAddr {
V4(String),
V6(String),
}
let home = IpAddr::V4(String::from("127.0.0.1"));enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));struct Ipv4Addr { ... }
struct Ipv6Addr { ... }
enum IpAddr {
V4(Ipv4Addr),
V6(Ipv6Addr),
}Defined by the standard library:
enum Option<T> {
None,
Some(T),
}let some_number = Some(5);
let some_char = Some('e');
let absent_number: Option<i32> = None;let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
_ => reroll(), // or `_ => ()`
}enum Coin { Penny, Nickel, Quarter, }
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => { println!("Lucky penny!"); 1 }
Coin::Nickel => 5,
Coin::Quarter => 25,
}
}fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);let config_max = Some(3u8);
if let Some(max) = config_max {
println!("The maximum is configured to be {max}");
}let v: Vec<i32> = Vec::new();
v.push(1);
let v = vec![1, 2, 3];
let third: &i32 = &v[2];
let third: Option<&i32> = v.get(2);
for i in &v {
println!("{i}");
}
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
while let Some(top) = stack.pop() {
println!("{top}");
}let v = vec!['a', 'b', 'c'];
for (index, value) in v.iter().enumerate() {
println!("{value} is at index {index}");
}use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
let team_name = String::from("Blue");
let score = scores.get(&team_name).copied().unwrap_or(0);
scores.entry(String::from("Yellow")).or_insert(50);
for (key, value) in &scores {
println!("{key}: {value}");
}panic!("crash and burn");enum Result<T, E> {
Ok(T),
Err(E),
}
let greeting_file = match File::open("hello.txt") {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {error:?}"),
};use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
let mut username = String::new();
File::open("hello.txt")?.read_to_string(&mut username)?;
Ok(username)
}struct Point<T> {
x: T,
y: T,
}
let integer = Point { x: 5, y: 10 };
let float = Point { x: 1.0, y: 4.0 };struct Point<X1, Y1> {
x: X1,
y: Y1,
}
impl<X1, Y1> Point<X1, Y1> {
fn mixup<X2, Y2>(self, other: Point<X2, Y2>) -> Point<X1, Y2> {
Point {
x: self.x,
y: other.y,
}
}
}
impl Point<f32> {
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}pub trait Summary {
fn summarize(&self) -> String;
}
pub struct Article {
pub headline: String,
pub content: String,
}
impl Summary for Article {
fn summarize(&self) -> String {
format!("News: {}", self.headline)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
};
println!("1 new tweet: {}", tweet.summarize());
pub fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
// is syntactic sugar for:
pub fn notify<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
pub fn notify(item: &(impl Summary + Display)) { ...
// is syntactic sugar for:
pub fn notify<T: Summary + Display>(item: &T) { ...// default implementation (optional):
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
pub struct Article {
pub headline: String,
pub content: String,
}
impl Summary for Article { }Traits for any type that implements another trait
impl<T: Display> ToString for T {
...
}
let s = 3.to_string();cargo test --help
cargo test -- --help
cargo test -- --test-threads=1
cargo test -- --show-output
cargo test <test>
cargo test --test <test-in-"tests"-dir>
cargo test -- --ignoredpub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
#[test]
#[should_panic]
fn it_fails() {
...
}
#[test]
#[ignore]
fn it_is_ignored() {
...
}
}use std::thread;
use std::time::Duration;
let handle = thread::spawn(|| {
for i in 1..10 {
println!("hi number {i} from the spawned thread!");
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..5 {
println!("hi number {i} from the main thread!");
thread::sleep(Duration::from_millis(1));
}
handle.join().unwrap();use std::sync::mpsc;
use std::thread;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
});
let received = rx.recv().unwrap();
println!("Got: {received}");if let Some(x) = some_option_value {
println!("{x}");
}fn print_coordinates(&(x, y): &(i32, i32)) {
println!("Current location: ({x}, {y})");
}
let point = (3, 5);
print_coordinates(&point);let x = 1;
match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}let x = 5;
match x {
1..=5 => println!("one through five"),
_ => println!("something else"),
}let origin = Point { x: 0, y: 0, z: 0 };
match origin {
Point { x, .. } => println!("x is {x}"),
}let num = Some(4);
match num {
Some(x) if x % 2 == 0 => println!("The number {x} is even"), // a match guard
Some(x) => println!("The number {x} is odd"),
None => (),
}Macros are a way of writing code that writes other code, which is known as metaprogramming.
#[macro_export]
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}