Skip to content

Instantly share code, notes, and snippets.

@debasishg
Last active January 23, 2024 05:51
Show Gist options
  • Select an option

  • Save debasishg/0756ef48fa841a0f1c672c6b6a10c72a to your computer and use it in GitHub Desktop.

Select an option

Save debasishg/0756ef48fa841a0f1c672c6b6a10c72a to your computer and use it in GitHub Desktop.

Revisions

  1. debasishg revised this gist Jan 22, 2024. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions trait_bound.md
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ Here's one example from the book Rust for Rustaceans (a great book BTW).
    Suppose you want to construct a `HashMap<K, V, S>`, whose keys are some generic type `T`, value is a `usize`, you can write bounds like `T: Hash + Eq`, `S: BuildHasher + Default`.

    ```rust
    pub fn do_it<T>(value: T)
    pub fn doit<T>(value: T)
    where T: Hash + Eq {
    let mut h = HashMap::new();
    h.insert(value, 10usize);
    @@ -17,7 +17,7 @@ where T: Hash + Eq {
    But if you want to constrain your user to just use `.collect` and `from_iter()` on the `HashMap`, you can just write `HashMap<T, usize, S>: FromIterator`. With this bound, you want your user to be able to create the collection **only** from an iterator. Trying to use any other method like `.insert()` will give compilation error.

    ```rust
    pub fn do_it_again<T>(value: T)
    pub fn doit_again<T>(value: T)
    where HashMap<T, usize>: FromIterator<(T, usize)> {
    // `insert` will not be allowed by the compiler
    // let h: HashMap<T, usize>= HashMap::new();
  2. debasishg created this gist Jan 21, 2024.
    30 changes: 30 additions & 0 deletions trait_bound.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    ## Trait Bounds

    Trait bounds in Rust are really powerful and also offers lots of idiomatic ways to constrain your model. Bounds are for enforcing constraints even in other languages like Scala, but Rust offers them at a different level.

    Here's one example from the book Rust for Rustaceans (a great book BTW).

    Suppose you want to construct a `HashMap<K, V, S>`, whose keys are some generic type `T`, value is a `usize`, you can write bounds like `T: Hash + Eq`, `S: BuildHasher + Default`.

    ```rust
    pub fn do_it<T>(value: T)
    where T: Hash + Eq {
    let mut h = HashMap::new();
    h.insert(value, 10usize);
    }
    ```

    But if you want to constrain your user to just use `.collect` and `from_iter()` on the `HashMap`, you can just write `HashMap<T, usize, S>: FromIterator`. With this bound, you want your user to be able to create the collection **only** from an iterator. Trying to use any other method like `.insert()` will give compilation error.

    ```rust
    pub fn do_it_again<T>(value: T)
    where HashMap<T, usize>: FromIterator<(T, usize)> {
    // `insert` will not be allowed by the compiler
    // let h: HashMap<T, usize>= HashMap::new();
    // h.insert(value, 10usize);
    let iter = [(value, 10_usize)];
    let h = HashMap::from_iter(iter);
    }
    ```

    By constraining the bound, you make your model intent more explicit and clear.