Hierarchy of generics in RUST
Generics in RUST form a hierarchy from general to specific, similar to the base class and subclass relationship in object-oriented programming:
Base level: T: ?Sized
The constraint ?Sized
indicates all types.
First-level sub-level: Default memory fixed type T
; raw pointer type *const T
/ *mut T
; slice type [T]
; array type [T; N]
; reference type &T
/ &mut T
; trait constraint type T: trait
; generic tuple (T, U...)
; generic composite type struct<T>
; enum<T>
; union<T>
and specific types u8
/u16
/i8
/bool
/f32
/&str
/String
...
Second-level sub-level: Assign a specific type to T
in the first-level sub-level, such as *const u8
; [i32]
, or specialize T
in the first-level sub-level again, such as *const [T]
; [*const T]
; &(*const T)
; *const T where T: trait
; struct<T: trait>
This hierarchy can be recursively applied. Clearly, methods and traits implemented for base types can be applied to higher-level generic types. For example:
impl<T> Option<T> {...}
impl<T, U> Option<(T, U)> {...}
impl<T: Copy> Option<&T> {...}
impl<T: Default> Option<T> {...}
The above examples are different implementations of methods for different generics of Option
in the standard library. They follow the rule from general to specific.
Similar implementations can be demonstrated with the following examples:
impl<T: ?Sized> *const T {...}
impl<T: ?Sized> *const [T] {...}
impl<T: ?Sized> *mut T {...}
impl<T: ?Sized> *mut [T] {...}
impl<T> [T] {...}
impl<T, const N: usize> [T; N] {...}
impl AsRef<[u8]> for str {...}
impl AsRef<str> for str {...}
Regarding the generic type T
mentioned above, I have a question. If the first T
represents all types, does this include [T]
? In other words, is the type [i32]
considered part of T
or [T]
, or both?