# Blog post: Tour of Rust's Standard Library Traits

**URL:** <https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974>\
**Category:** tutorials\
**Created:** [April 6, 2021, 12:18pm UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974 "2021-04-06T12:18:08Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![pretzelhammer](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/pretzelhammer/32/15402_2.png) [@pretzelhammer](https://users.rust-lang.org/u/pretzelhammer)\
**Post date:** [April 6, 2021, 12:18pm UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/1 "2021-04-06T12:18:09Z")

</div>

I wrote [Tour of Rust's Standard Library Traits](https://github.com/pretzelhammer/rust-blog/blob/master/posts/tour-of-rusts-standard-library-traits.md) to teach Rust beginners about all of the different traits in the standard library and how they are used!

Please let me know if you find anything confusing, unclear, or inaccurate! Your feedback is very important and helps me improve the article. Thanks!

_Edit note: I don't actually go over every single trait in the standard library, just a curated list of traits which I think are the most commonly used and thus the must useful for beginners to learn about._

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/steffahn/32/47569_2.png) [@steffahn](https://users.rust-lang.org/u/steffahn)\
**Post date:** [April 6, 2021, 1:05pm UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/2 "2021-04-06T13:05:24Z")

</div>

> "Generic parameters" broadly refers to both generic type parameters and generic lifetime parameters.

Nowadays there’s also const generics. E.g.

```rust
trait Foo<const N: usize> {}

```

Regarding generics and traits, there might be value in trying to reproduce some of the gist of (my posts in) [this thread](https://users.rust-lang.org/t/trait-constructors/53522) – at least OP found it helpful there, this also plays into viewing traits with type arguments as a way to do multiple dispatch.

Depending on how long the “traits basics” is supposed to be you might want to mention orphan instances, too… oh wait

> The rules Rust uses to enforce trait coherence, the implications of those rules, and workarounds for the implications are outside the scope of this article.

maybe you at least want to mention the term “orphan impl” or “orphan rules” or link to something like [the reference](https://doc.rust-lang.org/stable/reference/items/implementations.html#trait-implementation-coherence) and/or [this post (which has more interesting links)](https://github.com/Ixrec/rust-orphan-rules). Also, since you explain blanket impls, you might want to mention that adding blanket impls can result in semver-breaking changes while adding ordinary impls is usually not (considered) a breaking change.

Your object safety definition seems off, in particular

> A trait method is object-safe if it meets these requirements:
> 
> - method requires `Self: Sized` or
> - method does not use `Self` anywhere other than the first argument

a method without an actual `self` parameter/receiver isn’t object safe either, e.g.

```rust
trait Foo {
    fn foo(this: Self);
}

impl dyn Foo {}

```

```rust
2 | trait Foo {
  | --- this trait cannot be made into an object...
3 | fn foo(this: Self);
  | ^^^ ...because associated function `foo` has no `self` parameter

```

you might want to copy/adapt the definition from [the reference](https://doc.rust-lang.org/stable/reference/items/traits.html#object-safety) more closely.

I don’t really love the term “impl’d”, I think “implemented” might be nicer. It also corresponds to how rustc always speaks of “implement” or “implementation”.

Your prelude listing doesn’t contain `IntoIterator` (and maybe some more are missing). You should double-check the list / recreate it from [the docs](https://doc.rust-lang.org/std/prelude/index.html).

> Almost all types are `Send` and `Sync` . The only notable `Send` exception is `Rc` and the only notable `Sync` exceptions are `Rc` , `Cell` , `RefCell` . If you need a `Send` version of `Rc` use `Arc` . If you need a `Sync` version of `Cell` or `RefCell` use `Mutex` or `RwLock` .

Maybe mention raw pointers not being send/sync and atomic types as an alternative for `Cell` (when applicable).

* * *

_Edit: Another point_

> #### Functions
> 
> A trait function is any function whose first argument is not of type `Self` or some type which dereferences to `Self` , e.g. `&Self` , `&mut Self` , `Box<Self>` .
> 
> #### Methods
> 
> A trait method is any function whose first argument is of type `Self` or some type which dereferences to `Self` , e.g. `&Self` , `&mut Self` , `Box<Self>` .
> 
> Methods can be called using the dot operator on the implementing type:

That’s inaccurate. The relevant difference is whether there’s a (first) parameter _called_ “`self`” (which is a keyword and can only be used for the first argument when the type is a valid receiver type). Also, valid receiver types (according to the reference) are only:

> If the type of the `self` parameter is specified, it is limited to types resolving to one generated by the following grammar (where `'lt` denotes some arbitrary lifetime):
> 
> ```rust
> P = &'lt S | &'lt mut S | Box<S> | Rc<S> | Arc<S> | Pin<P>
> S = Self | P
> 
> ```
> 
> The `Self` terminal in this grammar denotes a type resolving to the implementing type. This can also include the contextual type alias `Self` , other type aliases, or associated type projections resolving to the implementing type.

Also you define a “function”/“trait function” (which might IMO perhaps better be called an “ **associated** function” (effectively) as a function that is not a method. Then you say

> However methods are just functions with syntax sugar

It’s all a bit confusing; in my experience there is no real terminology for an associated funtion that is not a method. Also compare with [the reference](https://doc.rust-lang.org/stable/reference/items/associated-items.html#associated-functions-and-methods) on these definitions/terminology.

* * *

_Edit2:_

> However, the idiomatic refactor is actually:
> 
> ```rust
> fn example<I: Iterator<Item = i32>>(mut iter: I) {
> let first3: Vec<_> = (&mut iter).take(3).collect();
> for item in iter { // ✅
> // process remaining items
> }
> }
> 
> ```

I’d actually argue in favor of `iter.by_ref().take(3).collect()`. Also – even though it is useful to know that underscores can be used for this – I think that an explicit `Vec<i32>` annotation might be more clear in demonstrating that even though `&mut` or `by_ref()` is involved, the `Item` type stays the same.

> [@pretzelhammer](#):
>
> teach Rust beginners about all of the different traits in the standard library

Does that not include e.g. `DoubleEndedIterator`? It’s even in the prelude.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/steffahn/32/47569_2.png) [@steffahn](https://users.rust-lang.org/u/steffahn)\
**Post date:** [April 6, 2021, 10:37pm UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/3 "2021-04-06T22:37:02Z")

</div>

For `Iterator`, I would love a distinction between methods that one might want to overload and methods that one would _always_ want to keep default implemented. I'm actually not really aware of any preexisting list of “potentially useful to overload” iterator methods anywhere online, and maybe there's some methods where it's not totally clear if you'd ever want to touch them, but I think something like this would be super useful. Useful to the point of: It should probably also be added to the documentation of `Iterator` itself. For some trivial examples: `size_hint` and `nth` would definitely be on the list and `map` and `by_ref` would _not_ be on it.

Also maybe, to keep it short, in this tutorial you would only want to list a few most commonly overloaded methods of iterator including `size_hint` and maybe `fold`. And `nth` and `last`.

---

<div class="post-metadata">

**Author:** ![Yandros](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/yandros/32/8136_2.png) [@Yandros](https://users.rust-lang.org/u/Yandros)\
**Post date:** [April 6, 2021, 11:38pm UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/4 "2021-04-06T23:38:14Z")

</div>

The blog post looks nice, good job! (haven't finished reading it).

One thing, though, before I forget: the prelude module used to be named `v1`, now it is called `rust_20xx` to match each edition, since Rust editions can now affect which prelude ends up used (for instance, `Try{From,Into}` will be in the 2021 edition) 🙂

* * *

Second thing:

> [@](#):
>
> The standard library exports a handful of derive macros which we can use to quickly and conveniently impl a trait on a type **if all of its members also impl the trait**.
> 
> [...]
> 
> Note: derive macros are just procedural macros and can do anything, there's no hard rule that they must impl a trait or **that they can only work if all the members of the type impl a trait, these are just the conventions followed by the derive macros in the standard library**.

This could be an excellent occasion to mention (possibly through a footnote, to avoid info overload), that the derives in the standard library implement a trait:

- **_if/when_ the type parameters** (≠ types of the members) **`impl`ement said trait** ,

- and _requires_ that the types of the members then implement said trait.

I'm saying this because it can be confusing (I personaly find it to be an inconsistency within the standard library derives' design) that:

```rust
#[derive(Clone, Copy)] // `Ptr_String : Copy`
struct Ptr_String(*const String);

// but:
#[derive(Clone, Copy)] // `Ptr<String>` is *not* `Copy`!
struct Ptr<S>(*const S);

```

---

<div class="post-metadata">

**Author:** ![keras](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/keras/32/17581_2.png) [@keras](https://users.rust-lang.org/u/keras)\
**Post date:** [April 7, 2021, 2:30am UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/5 "2021-04-07T02:30:35Z")

</div>

It’s that kind of content that I like, I’ll follow the discussion here as well

---

<div class="post-metadata">

**Author:** ![EdmundsEcho](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/edmundsecho/32/18445_2.png) [@EdmundsEcho](https://users.rust-lang.org/u/EdmundsEcho)\
**Post date:** [April 15, 2021, 3:38am UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/6 "2021-04-15T03:38:05Z")

</div>

> [@steffahn](#):
>
> including `size_hint` and maybe `fold` .

What’s the motivation for overloading `fold`?

---

<div class="post-metadata">

**Author:** ![EdmundsEcho](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/edmundsecho/32/18445_2.png) [@EdmundsEcho](https://users.rust-lang.org/u/EdmundsEcho)\
**Post date:** [April 15, 2021, 3:47am UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/7 "2021-04-15T03:47:27Z")

</div>

Feel free to steal anything [from the following](https://drive.google.com/file/d/1AQ9LCjHewAxgByGF-tb05NAA_7tt0Q7k/view) description of how Rust goes about iteration. It’s more describing the whole from the parts.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/steffahn/32/47569_2.png) [@steffahn](https://users.rust-lang.org/u/steffahn)\
**Post date:** [April 15, 2021, 4:01am UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/8 "2021-04-15T04:01:26Z")

</div>

It increases performance for iterators where repeatedly calling `next` has overhead. The classical example is `chain`, where every single `next` call would have to execute a test of whether the iteration is currently still in the first iterator or still in the second. For deeply nested iterator chains this can even make a difference in terms of asymptotic execution time of an iteration.

Actually, that s just the benefit of overloading `try_fold` (once overloading `try_fold` even becomes possible). Overloading `fold` has the additional advantage that it becomes entirely unnecessary to track the progress of iteration inside of the iterator itself, since the iterator gets passed by-value and isn't needed anymore after the iteration which proceeds all the way until the end.

The choice of `fold` over e.g. `for_each` or others for overloading is also due to the fact that many other methods like `sum` or indeed `for_each` are defined using `fold` (in their default implementation).

Another example next to `chain` is `x..=y` inclusive ranges. Those use a flag internally to store if iteration has finished. The reason why something like this is necessary is that e. g. `0_u8..=255_u8` has a total of `257` iterator states, since it yields a total of `256` numbers followed by a `None`. Its `next` method needs to check this extra flag on every call, something like `fold` only needs to check it once in the beginning.

---

<div class="post-metadata">

**Author:** ![EdmundsEcho](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/edmundsecho/32/18445_2.png) [@EdmundsEcho](https://users.rust-lang.org/u/EdmundsEcho)\
**Post date:** [April 15, 2021, 11:54pm UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/9 "2021-04-15T23:54:02Z")

</div>

> [@steffahn](#):
>
> something like `fold` only needs to check it once in the beginning

... if overwritten or in what has already been implemented?

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/steffahn/32/47569_2.png) [@steffahn](https://users.rust-lang.org/u/steffahn)\
**Post date:** [April 16, 2021, 7:26am UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/10 "2021-04-16T07:26:48Z")

</div>

If overwritten. Well, for `RangeInclusive` [the implementation _is_ overwritten](https://doc.rust-lang.org/1.51.0/src/core/iter/range.rs.html#739-751), so it's not much of an “if”, but if course I'm also implicitly talking about what reasons for doing so would be for custom iterators with similarities to `RangeInclusive`.

The default implementation of `fold` used to use `try_fold` in the past IIRC, but currently it's using repeated calls to `next`, so without any overloading of `fold` there's no advantage that `fold` can have over `next`.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [July 15, 2021, 7:27am UTC](https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974/11 "2021-07-15T07:27:25Z")

</div>

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
