{"id":18260072,"url":"https://github.com/roppa/learning-rust","last_synced_at":"2025-04-08T23:44:43.371Z","repository":{"id":146092727,"uuid":"203594377","full_name":"roppa/learning-rust","owner":"roppa","description":"Learning Rust","archived":false,"fork":false,"pushed_at":"2020-03-29T10:55:41.000Z","size":30,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-14T18:36:29.295Z","etag":null,"topics":["cargo","language","rust","toml"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/roppa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-21T13:51:22.000Z","updated_at":"2020-03-29T10:55:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"b5ebeb18-780f-4929-b0b1-b299e0168c28","html_url":"https://github.com/roppa/learning-rust","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roppa%2Flearning-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roppa%2Flearning-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roppa%2Flearning-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roppa%2Flearning-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roppa","download_url":"https://codeload.github.com/roppa/learning-rust/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247947825,"owners_count":21023058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cargo","language","rust","toml"],"created_at":"2024-11-05T10:41:55.284Z","updated_at":"2025-04-08T23:44:43.356Z","avatar_url":"https://github.com/roppa.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Learning Rust\n\nOne of the first things I like to do after gaining some familiarity with a language is a couple of katas, maybe Blackjack, an API of some sort. All test driven of course. Thats what we'll do here.\n\nWhat I find sorely missing in education is hierarchy of knowledge. Most resources give you every single bit of data related to a subject with equal stress. For example, with a written language a hierarchy of knowledge would be:\n\n- alphabet\n- words\n- grammar\n- structure\n\nSo, for a new language I first learn the alphabet (operators), words (reserved words), grammar (syntax), structure (files, modules, tests). The things usually used 80% of the time should be **emphasized** whereas edge cases would probably be an aside or in an appendix.\n\n## Definitions\n\nRust is a [system language](https://en.wikipedia.org/wiki/System_programming_language), meaning it can be used for low level stuff such as Operating Systems, hardware and the like. That doesn't mean it is limited to those however.\n\nWhy Rust? What makes Rust great?:\n\n- high level language with low level capabilities\n- strongly typed\n- no garbage collector, instead tracking it itself\n- concurrency built in\n- blazingly fast (because of the above)\n\nRust has a steep learning curve however.\n\n## Style\n\nRust has an opinionated coding style:\n\n- indentations are 4 spaces\n- variable names are snake case\n\nBut, before the Rust fundamentals, lets talk about the build runner, documentation generator, test runner and package manager - Cargo.\n\n## Cargo\n\nAssuming you have installed Rust, go ahead and run this:\n\n```bash\ncargo new hello\n```\n\nThis creates a folder:\n\n```bash\n└── hello\n    ├── Cargo.toml\n    └── src\n        └── main.rs\n```\n\nCargo.toml:\n\n```toml\n[package]\nname = \"hello\"\nversion = \"0.1.0\"\nauthors = [\"Your Name \u003cyou@your-email.com\u003e\"]\nedition = \"2018\"\n\n### See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n```\n\nAnd the rust file:\n\n```rust\nfn main() {\n    println!(\"Hello, world!\");\n}\n```\n\nFirst things first, the Cargo.toml file. This is the configuration file for your software. This has all the information about your project, the name, authors, version (semver), project name (used when importing files) etc. It is also where other package dependencies are imported.\n\nThe rust file that is generated is a 'hello world' by default.\n\nNow you can create an executable by running `cargo build`. Then execute by running `cargo run` (`cargo run` by itself builds and then runs).\n\nAfter you run `build` you will see a 'target' folder is created. in the target folder is 'debug', so you probably want to add this to your `.gitignore` file.\n\n## Main\n\nThe genesis of your project is the `main` function. This is what is executed when you run.\n\n```rust\nfn main() {}\n```\n\nFunctions are declared with a `fn` then name, parenthesis, then the body is in braces.\n\n## Types\n\nIntegers are signed or unsigned: 8, 16, 32, 64, 128 (usize and isize). i32 or u32 etc.\n\nYou can use binary: 0b, octal: 0o, hex: 0x.\n\nFloats are f32 and f64. This is valid: 0.1, this is not: .1.\n\nBool is `bool`, which are `true` and `false`.\n\nA char is 4 bytes, a scalar, differing from a character within a string, which is utf-8 2 bytes.\n\nTuple stores multiple values, accessed by dot syntax (maximum of 12):\n\n```rust\nlet a = (1, 2, 3);\nprintln!(\"{}, {}, {}\", a.0, a.1, a.2);\n```\n\nArrays are limited to 32 length. Vectors are preferred over Arrays.\n\nTo inspect an array use `println!(\"{:?}\", arr);`.\n\n## Variables\n\nVariables are immutable in Rust, however, you can mutate them by declaring using `let mut`. Rust is strongly typed, but if it can deduce what the variable is, it will automatically create that type for you.\n\n```rust\nlet [mut] [variable-name][: type] = [value];\n```\n\nJust so we can see something, Rust uses the format `println!` to write to the console, more on this later, but notice the exclamation mark before the parenthesis. Also, when you see a `{}` that means it will be replaced by the params you pass after the string.\n\n```rust\nlet a = 34;\nprintln!(\"Rust can deduce what type you want: {}\", a);\n\nlet a:u32 = 34;\nprintln!(\"Or, you could add the unsigned integer 32 bit `:u32` type {}\", a);\n\nlet mut change = 34;\nchange += 1;\nprintln!(\"This value is mutable, therefore changed {}\", change);\n\nlet string = \"Hello world!\";\nprintln!(\"{}\", string);\n```\n\nWe'll come back to strings.\n\n`const` always uses SCREAMING snake case, and you MUST specify type. Consts are really fast to access. You can use them 'globally' i.e. outside functions.\n\n```rust\nconst UNCHANGING:u32 = 123;\nprintln!(\"Const value is {}\", UNCHANGING);\n```\n\nYou can destructure values and assign like this:\n\n```rust\nlet (var1, var2) = (1, 2);\n```\n\n## Structs\n\nStructs are types that you define. You can access the attributes of the data type using dot notation.\n\n```rust\nstruct User {\n    name: String,\n    email: String,\n    age: i32\n}\n\nfn main() {\n    let bob = User{\n        name: \"Bob\".to_string(),\n        email: \"bob@bobbity.com\".to_string(),\n        age: 32\n    };\n\n    println!(\"Bob is: {}, {}, {}\", bob.name, bob.email, bob.age);\n}\n```\n\n## Help from the Compiler\n\nWhen you get compile errors, Rust gives you a handy explain command: `rustc --explain E0384`. Run that to get more information on the error. Pretty useful stuff.\n\n## Blocks and Scope\n\nScope in Rust is block level. It does have access to parent scope (nested blocks). A block can be created with braces `{}`, as in:\n\n```rust\nfn main() {\n    {\n        let x = 1;\n        println!(\"{}\", x);\n    }\n}\n```\n\nVariables can also be 'shadowed', so you can declare the same variable name multiple times.\n\n## Functions\n\n```\nfn [snake_case function name]([param :type]) -\u003e [return type]\n```\n\nFor example:\n\n```rust\nfn volume(x: i32, y: i32, z: i32) -\u003e i32 {\n    return x * y * z;\n}\n\n```\n\nWith the returned value, if you leave off the trailing semicolon of an expression, that value gets returned. (remember, an expression is anything that results in a value).\n\n```rust\nfn volume(x: i32, y: i32, z: i32) -\u003e i32 {\n    x * y * z\n}\n```\n\nNote: you know the `println!`, see the exclamation mark? That is a 'macro'. A macro is a type of function (more later). You can use macros when you do not have a fixed arity.\n\n## Operators and Control Flow\n\nOperators are just like C like languges, such as `+`, `-`, `!`, `\u0026\u0026`, `||`, `==`, `%`.\n\nRust does not have a ternery operator because of the way if/else logic works. Notice there is no semi-colon, meaning the expression is returned. For example:\n\n```rust\nlet toggle = if toggle == 0 { 1 } else { 0 };\n```\n\nRemember in TDD you start off with an if/else for one condition, then change it into a while/for etc. Look Mom, no brackets.\n\n```rust\nlet n = 0;\nif n == 0 {\n    println!(\"Oh\");\n} else {\n    println!(\"Uh oh\");\n}\n```\n\n## Loops\n\nInfinite loop is:\n\n```rust\nprint!(\"N\");\nloop {\n    print!(\"o\");\n}\n```\n\nTo escape, use `break`.\n\nWhile:\n\n```rust\nlet mut n = 0;\nwhile n \u003c 10 {\n    n += 1;\n}\n```\n\nFor:\n\n```rust\nfor x in 1..101 {\n    if x % 3 == 0 \u0026\u0026 x % 5 == 0 {\n        result = format!(\"{}{}\\n\", result, \"FizzBuzz\");\n    } else if x % 5 == 0 {\n        result = format!(\"{}{}\\n\", result, \"Buzz\");\n    } else if x % 3 == 0 {\n        result = format!(\"{}{}\\n\", result, \"Fizz\");\n    } else {\n        result = format!(\"{}{}\\n\", result, x.to_string());\n    }\n}\n```\n\nThere are iterators too which we'll come to later.\n\n## Important files\n\nThe important files are: `main.rs`, `lib.rs` and `mod.rs`.\n\n`main.rs` and `lib.rs` 'crate roots' - contents of either form a module named 'crate' at the root of the crate’s module structure (module tree). Basically a module can be a single file, or a file in a folder. If it is in a folder, you need\n\nYou can create module in two ways either a single file or a file within folder.\n\n## Code Structure\n\nTerms are: `crate`, `module`, `path`, `use`, `pub`, `as`.\n\n## Tests\n\nLike all good languages, testing is built in to Rust. Tests go in the file they are testing. The convention is to use a `tests` module in each file, annotating with `cfg(test)`:\n\n```rust\n#[cfg(test)]\nmod tests {\n    #[test]\n    fn addition_works() {\n        assert_eq!(2 + 2, 4);\n    }\n}\n```\n\n## Ownership and References\n\nRust does not have a garbage collector.\n\n## Command line\n\nTo access args you can use `std::env::args()`. This gets them once the program is called:\n\n```rust\nlet args: Vec\u003cString\u003e = std::env::args().skip(1).collect();\nprintln!(\"{:?}\", args);\n```\n\nThis loops over input:\n\n```rust\nuse std::io;\nuse std::io::prelude::*;\n\nfn main() {\n    let stdin = io::stdin();\n    for line in stdin.lock().lines() {\n        let input = line.unwrap();\n        println!(\"you entered {}\", input);\n    }\n}\n```\n\n## System Libraries\n\n```rust\nuse std::{thread, time};\n\nfn main() {\n    let one_second = time::Duration::from_millis(1000);\n    print!(\"Hello, world!\");\n    thread::sleep(one_second);\n    print!(\"Hello, world!\");\n    thread::sleep(one_second);\n    print!(\"Hello, world!\");\n}\n```\n\n## Tools\n\n- [Rust playground](https://play.rust-lang.org/)\n\n## Resources\n\n- [Actix api framework](https://actix.rs)\n- [Crates](https://crates.io/)\n\n## References\n\n- [CleanCut Rust course](https://github.com/CleanCut/rust_programming/)\n- [Rust loops](https://doc.rust-lang.org/1.6.0/book/loops.html)\n- [Modules](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html)\n- [Rust unit test](https://doc.rust-lang.org/book/ch11-03-test-organization.html)\n- [Rust modules](https://medium.com/@tak2siva/rust-modules-explained-96809931bbbf)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froppa%2Flearning-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froppa%2Flearning-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froppa%2Flearning-rust/lists"}