1974 shaares
6 private links
6 private links
Trait Basics
Self always refers to the implementing type.
- Use associated types when there should only be a single impl of the trait per type.
- Use generic types when there can be many possible impls of the trait per type.
In other words, we can't "clone" a &str into a String, or a &Path into a PathBuf, or an &OsStr into an OsString, since the clone method signature doesn't support this kind of cross-type cloning, and that's what ToOwned was made for.
&[u8] impls Read and that Vec<u8> impls Write so we can easily unit test our file handling functions using Strings which are trivial to convert to &[u8] and from Vec<u8>
If a type is Sized that means its size in bytes is known at compile-time and it's possible to put instances of the type on the stack.
1. All generic types get an implicit Sized bound.
2. Since there's an implicit Sized bound on all generic types, if we want to opt-out of this implicit bound we need to use the special "relaxed bound" syntax ?Sized which currently only exists for the Sized trait:
3. There's an implicit ?Sized bound on all traits.
If a type is Send that means it's safe to send between threads. If a type is Sync that means it's safe to share references of it between threads. In more precise terms some type T is Sync if and only if &T is Send.
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 we need a Send version of Rc we can use Arc. If we need a Sync version of Cell or RefCell we can Mutex or RwLock. Although if we're using the Mutex or RwLock to just wrap a primitive type it's often better to use the atomic primitive types provided by the standard library such as AtomicBool, AtomicI32, AtomicUsize, and so on.