Associated Type in Rust

20-09-20 编程 #rust

Associated Type and generic diff in rust

type outside impl

a type Foo = Bar outside is just type alias. most used in generic type.

like: type Thunk = Box<dyn Fn() + Send + 'static>;

type inside impl

type in an impl defines an associated type. associated type 可以理解为一个类型占位符,在 trait 的方法声明中使用。

pub trait Iterator {
    type Item; // or type T: Display;

    fn next(&mut self) -> Option<Self::Item>;
}

这里 Iterator 的 Implementors 将会指定 Item 的具体类型。例如:

impl Iterator for Counter {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        // --snip--
    }
}

diff in associated type and generic

直接将上面的Iterator声明为如下泛型不是更简单么?

pub trait Iterator<T> { 
    fn next(&mut self) -> Option<T>;
}
//  with generice, you can set default type:
/// trait Iterator<T = String>
///    where T: Display,

主要的区别就是 generic 可是有任意多个实现,因为Iterator<Foo>Iterator<Bar>是两个不同的类型。
而 associated type 只能有一个实现,因为Iterator只有一个类型,所以 associated type 可以用于限制类型。

when use

The quick and dirty answer to when to use generics and when to use associated types is:
Use generics if it makes sense to have multiple implementations of a trait for a specific type (such as the From<T> trait).
Otherwise, use associated types (like Iterator and Deref).

假设我们实现一个 redis 客户端,那么比较适合使用 associated types:

trait RedisCommand{
    type Response;
    fn receive(&self, message: String) -> Result<Self::Response>;
}

impl RedisCommand for PingCommand {
    type Response = String
    
    fn receive(&self, message: String) -> Result<Self::Response>{
        // -- snip --
    }
}