Rust-blog - Educational blog posts for Rust beginners

Overview

pretzelhammer's Rust blog 🦀

I write educational content for Rust beginners and Rust advanced beginners.

My posts are listed below in reverse chronological order.

Date Title Translations
2021-05-11 RESTful API in Sync & Async Rust
2021-03-31 Tour of Rust's Standard Library Traits 中文
2020-11-01 Learn Assembly with Entirely Too Many Brainfuck Compilers
2020-07-22 Sizedness in Rust
2020-05-19 Common Rust Lifetime Misconceptions русский · 日本語 · 中文
2020-05-09 Learning Rust in 2020
2020-05-02 Why blog?

Note: Translations are community-maintained.

Notifications

Get notified when a blog post get published by

Feedback

If you have any feedback please feel welcome to open an issue on this repo. I accept pull requests for minor fixes like typos and grammar.

Discuss

This repo has a discussion forum! Feel free to ask questions or start discussions.

Translations

If you wanna translate a blog post into another language that's awesome! Please feel free to fork this repo and promote your translation however you like. I also accept pull requests for translations if you'd like to host your translation on my blog directly.

Licensing

To be compatible with Rust, all code examples in this blog are licensed under Apache License Version 2.0 or MIT License, at your option.

I'd like to retain exclusive rights to the English version of the posts themselves, but as mentioned above if you translate a post into another language you're welcome to promote your translations however you like.

Comments
  • Remove static mut example

    Remove static mut example

    In the blog post about lifetimes, the following code snippet is used:

    static BYTES: [u8; 3] = [1, 2, 3];
    static mut MUT_BYTES: [u8; 3] = [1, 2, 3];
    
    fn main() {
       MUT_BYTES[0] = 99; // compile error, mutating static is unsafe
    
        unsafe {
            MUT_BYTES[0] = 99;
            assert_eq!(99, MUT_BYTES[0]);
        }
    }
    

    There has been some controversy surrounding this feature (internals, blog), some even calling this a "misfeature" in dire need of replacement. Because they appear deceptively easy to use correctly (I think it's unproblematic here, given that indexing an array is a built-in, and not a call to index_mut which AFAIK is UB), perhaps at least a warning should be added that this is non-trivial.

    opened by troublescooter 8
  • My benchmark results

    My benchmark results

    I'm confused and wondering why are the results so different 🤔

    I'm using the latest nightly, which is 1.54.0 and node 16.0.0. All tests are just for "Read". So I tested the same code in master on my local machine, which is: Desktop Linux, i7 3GHz, 8 core (8 thread), 16GB memory 2667MHz

    SA
    
    Requests      [total, rate, throughput]         1060260, 17670.99, 17670.37
    Duration      [total, attack, wait]             1m0s, 1m0s, 2.106ms
    Latencies     [min, mean, 50, 90, 95, 99, max]  334.431µs, 2.219ms, 2.072ms, 2.965ms, 3.393ms, 5.35ms, 48.375ms
    Bytes In      [total, mean]                     202156240, 190.67
    Bytes Out     [total, mean]                     0, 0.00
    Success       [ratio]                           100.00%
    Status Codes  [code:count]                      200:1060260
    
    DR
    
    LATEST THROUGHPUT INFO
    Requests      [total, rate, throughput]         588250, 9804.16, 9803.81
    Duration      [total, attack, wait]             1m0s, 1m0s, 2.135ms
    Latencies     [min, mean, 50, 90, 95, 99, max]  373.671µs, 3.867ms, 3.614ms, 5.928ms, 6.807ms, 8.765ms, 31.832ms
    Bytes In      [total, mean]                     112159696, 190.67
    Bytes Out     [total, mean]                     0, 0.00
    Success       [ratio]                           100.00%
    Status Codes  [code:count]                      200:588250 
    
    PEM
    
    LATEST THROUGHPUT INFO
    Requests      [total, rate, throughput]         650226, 10837.10, 10836.52
    Duration      [total, attack, wait]             1m0s, 1m0s, 3.258ms
    Latencies     [min, mean, 50, 90, 95, 99, max]  421.593µs, 3.662ms, 3.206ms, 6.278ms, 7.571ms, 10.887ms, 135.706ms
    Bytes In      [total, mean]                     124626650, 191.67
    Bytes Out     [total, mean]                     0, 0.00
    Success       [ratio]                           100.00%
    Status Codes  [code:count]                      200:650226  
    

    I ran it also on another machine, Laptop Linux, i9 2.4GHz, 8 core (16 thread), 32GB memory 3200MHz, and faced completely different result:

    SA
    
    LATEST THROUGHPUT INFO
    Requests      [total, rate, throughput]         1101823, 18363.66, 18363.24
    Duration      [total, attack, wait]             1m0s, 1m0s, 1.366ms
    Latencies     [min, mean, 50, 90, 95, 99, max]  365.511µs, 2.101ms, 1.935ms, 2.995ms, 3.492ms, 4.689ms, 43.751ms
    Bytes In      [total, mean]                     210080948, 190.67
    Bytes Out     [total, mean]                     0, 0.00
    Success       [ratio]                           100.00%
    Status Codes  [code:count]                      200:1101823
    
    DR
    
    LATEST THROUGHPUT INFO
    Requests      [total, rate, throughput]         218746, 3645.42, 3645.34
    Duration      [total, attack, wait]             1m0s, 1m0s, 1.195ms
    Latencies     [min, mean, 50, 90, 95, 99, max]  536.327µs, 10.683ms, 10.52ms, 20.746ms, 24.02ms, 29.712ms, 136.249ms
    Bytes In      [total, mean]                     41707600, 190.67
    Bytes Out     [total, mean]                     0, 0.00
    Success       [ratio]                           100.00%
    Status Codes  [code:count]                      200:218746
    
    PEM
    
    LATEST THROUGHPUT INFO
    Requests      [total, rate, throughput]         656688, 10944.79, 10944.22
    Duration      [total, attack, wait]             1m0s, 1m0s, 3.115ms
    Latencies     [min, mean, 50, 90, 95, 99, max]  553.575µs, 3.541ms, 3.302ms, 5.437ms, 6.413ms, 9.094ms, 162.15ms
    Bytes In      [total, mean]                     125865200, 191.67
    Bytes Out     [total, mean]                     0, 0.00
    Success       [ratio]                           100.00%
    Status Codes  [code:count]                      200:656688
    

    Now I have two questions: 1- Why is it completely different from what we have here in the blog post? 2- Why DR is so much different on these two machines?! (I ran them several times, it's almost the same)

    opened by omid 5
  • Mention that Read & Write aren't in the prelude when talking about Generic blanket impls

    Mention that Read & Write aren't in the prelude when talking about Generic blanket impls

    First off, amazing article! Thanks so much for writing it, it looks like a great reference and I've learnt way more than I probabaly need to know 😅.

    In the Read & Write section you mention the Generic blanket impls. You already mention this in the Scope section, but I think it's worth reiterating that Read & Write aren't in the prelude so if you want to use these blanket impls you need to bring them into scope. I think it's a common enough gottcha that a lot of people would be thankfull to be reminded.

    opened by Akeboshiwind 4
  • subjective issue, idk what title to give

    subjective issue, idk what title to give

    Hey, I just started reading the too many brainfuck compilers article and it is very interesting, however, I immediately noticed a code smell I would instantly refactor - it is subjective and I may be wrong by making a whole issue about it, but here it is:

    So you have a code that looks like:

    pub enum Inst {
        IncPtr(usize),
        DecPtr(usize),
        IncByte(usize),
        DecByte(usize),
        WriteByte(usize),
        ReadByte(usize),
        LoopStart(usize, usize),
        LoopEnd(usize, usize),
    }
    

    Then you spend extra 3 lines of the article ~~documenting~~ explaining what are these usizes for, but this can be easily made into a self-documented and much more readable code (and at places where you use it too). For example (with compact formatting here in the issue):

    pub enum Inst {
        IncPtr { by: usize },
        DecPtr { by: usize },
        IncByte { by: usize },
        DecByte { by: usize },
        WriteByte { times: usize },
        ReadByte { times: usize },
        LoopStart { times: usize, end_idx: usize },
        LoopEnd { times: usize, start_idx: usize },
    }
    

    The run-length encoding is way too repetitive and by definition is in each enum variant, so it can be abstracted away in a struct:

    pub struct Inst {
        pub kind: InstKind,
        pub times: usize,
    }
    
    pub enum InstKind {
        IncPtr,
        DecPtr,
        IncByte,
        DecByte,
        WriteByte,
        ReadByte,
        LoopStart { end_idx: usize },
        LoopEnd { start_idx: usize },
    }
    

    This improves readability and usability by a lot with no downsides (not like there is or will be 7 layers of structs/enums), and I honestly don't really know why tuple structs even exist at all. As I've said, this is subjective, feel free to ignore this, it just immediately tingled me when I was reading your article (didn't even read past this yet, but it seems very-very interesting).

    opened by necauqua 3
  • Clarify a license for blog posts themselves

    Clarify a license for blog posts themselves

    Quite self-explanatory title. I want to translate one of your blog posts and publish it on a IT platform, namely habr.com, however, I am not sure if I am allowed to do so. Here are the relevant parts of Habr user agreement at the moment (emphasis mine):

    4.8. By accepting the terms and conditions of this Agreement, the User shall provide Habr with a free (non-exclusive) license for using the Content in the following ways:

    <...>

    • to distribute copies of the Content, i.e. to provide access to material reproduced in any material form, including through network and otherwise, as well as by selling, renting, leasing, lending, including importation for any of these purposes (right of distribution);

    <...>

    • right to assign all or part of the received rights to third parties (the right to sublicense).

    <...> 4.11. The User guarantees the right to use the Content under the terms and conditions of the aforementioned license to the extend required.

    Since you didn't specify a license for posts themselves, you still have the exclusive rights for all your content, thereby I can't even legally publish a translation, not only on Habr but anywhere.

    opened by AnthonyMikh 3
  • Question about leaking with static refs

    Question about leaking with static refs

    I'm trying to understand how leaking works in one of the &'static examples.

    It's possible to generate random dynamically allocated data at run-time and return 'static references to it at the cost of leaking memory.

    use rand;
    
    // generate random 'static str refs at run-time
    fn rand_str_generator() -> &'static str {
        let rand_string = rand::random::<u64>().to_string();
        Box::leak(rand_string.into_boxed_str())
    }
    

    Part of my confusion comes from the Box::leak method. The documentation says that it returns a reference to the boxed value. If a reference is returned, that means the data is still there and the program hasn't "forgotten" about it. Maybe I'm misunderstanding what it means to "leak" memory. Can you help me understand?

    opened by zmitchell 3
  • 9) downgrading mut refs to shared refs is safe: last example seems confusing

    9) downgrading mut refs to shared refs is safe: last example seems confusing

    In 9) downgrading mut refs to shared refs is safe the last example starts with a block commented with // drop the returned mut Player refs since we can't use them together anyway. Commenting out this block still allows the code to compile (playground), and its purpose is unclear to me. I think it might be better to just remove it?

    opened by BartMassey 3
  • Fix sizedness post typos

    Fix sizedness post typos

    Hello! First and foremost, I loved this post!! It's probably the best explanation on "sizedness" for Rust there is 😊

    So reading it, I've found a couple of typos, here's the fix!

    opened by evaporei 2
  • Chinese Translation Completed: Tour of Rust's Standard Library Traits

    Chinese Translation Completed: Tour of Rust's Standard Library Traits

    I am working on translating this article into Chinese.

    This is a semi-finished article.

    This article is so long that I need a lot of time.

    I hope other people know about my work to avoid repeated translations.

    opened by skanfd 2
  • PartialEq example isn't right

    PartialEq example isn't right

    The "Kelvin / Celcius / Fahrenheit" example for PartialEq isn't right, as floating point numbers suck.

    I expected to break transitivity, but it turns out even symmetry is broken fairly easily, see for example:

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=754a08485eb182e995f3e9889243dd81

    To fix, while much less fun, maybe do millimeters, centimeters, kilometers? If they are each stored as i32, you could make the millimeters in i64 for comparison, which deals with overflow.

    opened by ChrisJefferson 2
  • Confuse: lifetime with struct and self.

    Confuse: lifetime with struct and self.

    https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md

    #[derive(Debug)]
    struct NumRef<'a>(&'a i32);
    
    impl<'a> NumRef<'a> {
        // no more 'a on mut self
        fn some_method(&mut self) {}
    
        // above line desugars to
        fn some_method_desugared<'b>(&'b mut self){}
    }
    
    fn main() {
        let mut num_ref = NumRef(&5);
        num_ref.some_method();
        num_ref.some_method(); // compiles
        println!("{:?}", num_ref); // compiles
    }
    

    It seems you simply give the solution (let compiler handle the lifetime). but why? what the lifetime 'a in struct NumRef doing/restricting? what is lifetime 'a in fn main ? (desugar lifetime in fn main maybe helpful?)

    Thanks.

    opened by towry 2
  • Struct methods can also NOT have elided lifetimes right?

    Struct methods can also NOT have elided lifetimes right?

    The list of common misconceptions contains:

    if you've ever written a struct method ... then your code has generic elided lifetime annotations all over it.

    But that's not always true right?

    struct A {}
    impl A {
        fn method(self) -> A {
            self
        }
    }
    pub fn main() {
    	let a = A {};
    	a.method();
    
    }
    
    opened by davidatsurge 0
  • Misconception discussion: T is a superset of both &T and &mut T

    Misconception discussion: T is a superset of both &T and &mut T

    While it's true and can be presented with generics, maybe a note that the following is possible would be beneficial, so nobody erroneously extrapolates the rule:

    struct Foo();
    trait Trait {}
    impl Trait for Foo {}
    impl Trait for &Foo {}
    impl Trait for &mut Foo {}
    

    Like with impl Read for TcpStream and impl Read for &TcpStream.

    opened by wodny 0
  • Customer review for Rust on the eve of 2022

    Customer review for Rust on the eve of 2022

    I would want to read your "customer's review" after 1 and half years later you started blogging about Rust.

    Questions to be answered in the article from my point of view:

    • So far, how was your Rust journey?
    • Is the Rust ecosystem overperformed, underperformed, or average in terms of growth when you compare with your expectations a year ago?
    • Do you think that Rust adoption is increasing and Rust employee is on the demand?
    • What's the biggest disappointment? e.g. Some of the advanced Rust developers think that the requirement of unsafe becomes a disappointment since the sales pitch was about safety.
    • Do you remember a good problem exists in other languages that you use but not in Rust?
    • What is missing for now where you use Rust?

    PS: I've met with your blog through Learning Rust in 2020 while I was looking for upper-beginner content in Rust. The article is great but some parts might be outdated as there are updates on mentioned platforms.

    opened by mtunad 0
  • `asymmetry` requirements in `PartialOrd`

    `asymmetry` requirements in `PartialOrd`

    In the blog post tour of rust standard library traits, I feel the paragraph of asymmetry requirements in partial_cmp is not right:

    All PartialOrd impls must ensure that comparisons are asymmetric and transitive. That means for all a, b, and c:

    • a < b implies !(a > b) (asymmetry)
    • a < b && b < c implies a < c (transitivity)

    In the document for PartialOrd, there is no part about asymmetry. The requirements for partial_cmp is:

    The comparison must satisfy, for all a, b and c:

    • transitivity: a < b and b < c implies a < c. The same must hold for both == and >.
    • duality: a < b if and only if b > a.

    Maybe the document is updated and we should catch up?

    opened by VitalyAnkh 0
  • Request for additional example in closure/function lifetime elision distinction

    Request for additional example in closure/function lifetime elision distinction

    From here: https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md#10-closures-follow-the-same-lifetime-elision-rules-as-functions

    There's no good reason for this discrepancy. Closures were first implemented with different type inference semantics than functions and now we're stuck with it forever because to unify them at this point would be a breaking change.

    Would it be a breaking change? I'm struggling to come up with a example of a closure that currently compiles that would no longer compile if the elision rules were changed to match functions. A one-line example of such a closure would be illustrative and unobtrusive here. And in the event that the claim is mistaken, that would bode well for changing the language to remove this discrepancy.

    opened by bstrie 1
  • Paragraph about `T: 'static` is not right

    Paragraph about `T: 'static` is not right

    TL;DR The misconception that if T: 'static then T must be valid for the entire program ... is not a misconception. It's literally true, in a sort of pedantic way.

    The problem is that people conflate validity of types with lifetime of values. The fact that a type is valid for an entire duration of a program is disctinct from whether or not there are values of that type physically existing at some point or another.

    A type T: 'static is valid even before you create any values of it, in fact, it's valid even if it's absolutely impossible to create any values of it, such as with the ! or Infallible or similar types. On the other hand, a non-static type can only be referred to in some part of a program where the type contains some specific lifetime, which only exists in that part of the prorgam. Again, this is distinct from any actual values of that type - those might not exist either.

    As a consequence, leaking is completely unrelated to whether a type is 'static or not, since leaking deals with values. You can leak values of non-static types just fine. I'm afraid mentioning leaking in that section only increases the confusion.

    Here's a demonstration of this:

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3615f118612c24891f44e2e0c820d3a5

    Hopefully this'll make sense. It's kind of hard to show this in an actual code, since I don't think there's a way of implementing functions for a non-static type only (there's no non-static marker trait etc.).

    opened by vojtechkral 8
Releases(restful-api-in-sync-async-rust)
Owner
kirill
kirill
Blog posts, mostly about Rust.

Sean Chen's Blog ?? Blog posts, mostly about Rust. Posts Date Title 2021-04-06 A Beginner's Guide to Handling Errors in Rust 2021-01-23 Implementing a

Sean Chen 13 Sep 4, 2022
A Matrix bot which can generate "This Week in X" like blog posts

hebbot A Matrix bot which can help to generate periodic / recurrent summary blog posts (also known as "This Week in X"). The bot was inspired by twim-

Häcker Felix 43 Dec 17, 2022
A tray application for Windows that gives you push notifications and instant downloads of new posts, messages and stories posted by models you subscribe to on Onlyfans.

OF-notifier A tray application for Windows that gives you push notifications and instant downloads of new posts, messages and stories posted by models

Gentlemen Mercenary 10 Dec 20, 2022
An LR(1) parser generator and visualizer created for educational purposes.

.lr An LR(1) parser generator and visualizer created for educational purposes. Table of Contents What is an LR(1) parser? Why did you make this? How c

Umut 80 Oct 21, 2024
This blog provides detailed status updates and useful information about Theseus OS and its development

The Theseus OS Blog This blog provides detailed status updates and useful information about Theseus OS and its development. Attribution This blog was

Theseus OS 1 Apr 14, 2022
Zomby7e's Blog - Backend

7eblog_backend Zomby7e's Blog - Backend, is just a micro blog backend. This project is written in Rust, it depends on Actix, uses SQLite to store data

Zomby7e 2 Aug 26, 2022
Code for blog post "{n} times faster than C, where n = 128"

Code for {n} times faster than C, where n = 128 Actually, n = 290 ?? Benchmark Setup Rust version: rustc 1.70.0 (90c541806 2023-05-31) Run test: cargo

Thomas Ip 9 Jul 24, 2023
Leetcode Solutions in Rust, Advent of Code Solutions in Rust and more

RUST GYM Rust Solutions Leetcode Solutions in Rust AdventOfCode Solutions in Rust This project demostrates how to create Data Structures and to implem

Larry Fantasy 635 Jan 3, 2023
Simple autoclicker written in Rust, to learn the Rust language.

RClicker is an autoclicker written in Rust, written to learn more about the Rust programming language. RClicker was was written by me to learn more ab

null 7 Nov 15, 2022
Rust programs written entirely in Rust

mustang Programs written entirely in Rust Mustang is a system for building programs built entirely in Rust, meaning they do not depend on any part of

Dan Gohman 561 Dec 26, 2022
Rust 核心库和标准库的源码级中文翻译,可作为 IDE 工具的智能提示 (Rust core library and standard library translation. can be used as IntelliSense for IDE tools)

Rust 标准库中文版 这是翻译 Rust 库 的地方, 相关源代码来自于 https://github.com/rust-lang/rust。 如果您不会说英语,那么拥有使用中文的文档至关重要,即使您会说英语,使用母语也仍然能让您感到愉快。Rust 标准库是高质量的,不管是新手还是老手,都可以从中

wtklbm 493 Jan 4, 2023
A library for extracting #[no_mangle] pub extern "C" functions (https://docs.rust-embedded.org/book/interoperability/rust-with-c.html#no_mangle)

A library for extracting #[no_mangle] pub extern "C" functions In order to expose a function with C binary interface for interoperability with other p

Dmitrii - Demenev 0 Feb 17, 2022
clone of grep cli written in Rust. From Chapter 12 of the Rust Programming Language book

minigrep is a clone of the grep cli in rust Minigrep will find a query string in a file. To test it out, clone the project and run cargo run body poem

Raunak Singh 1 Dec 14, 2021
The ray tracer challenge in rust - Repository to follow my development of "The Raytracer Challenge" book by Jamis Buck in the language Rust

The Ray Tracer Challenge This repository contains all the code written, while step by implementing Ray Tracer, based on the book "The Ray Tracer Chall

Jakob Westhoff 54 Dec 25, 2022
Learn-rust-the-hard-way - "Learn C The Hard Way" by Zed Shaw Converted to Rust

Learn Rust The Hard Way This is an implementation of Zed Shaw's Learn X The Hard Way for the Rust Programming Language. Installing Rust TODO: Instruct

Ryan Levick 309 Dec 8, 2022
Learn to write Rust procedural macros [Rust Latam conference, Montevideo Uruguay, March 2019]

Rust Latam: procedural macros workshop This repo contains a selection of projects designed to learn to write Rust procedural macros — Rust code that g

David Tolnay 2.5k Dec 29, 2022
The Rust Compiler Collection is a collection of compilers for various languages, written with The Rust Programming Language.

rcc The Rust Compiler Collection is a collection of compilers for various languages, written with The Rust Programming Language. Compilers Language Co

null 2 Jan 17, 2022
Integra8 rust integration test framework Rust with a focus on productivity, extensibility, and speed.

integra8 Integra8 rust integration test framework Rust with a focus on productivity, extensibility, and speed. | This repo is in a "work in progress"

exceptional 3 Sep 26, 2022
Neofetch but in Rust (rust-toml-fetch)

rtfetch Configuration Recompile each time you change the config file logo = "arch.logo" # in src/assets. info = [ "", "", "<yellow>{host_n

Paolo Bettelini 6 Jun 6, 2022