> For the complete documentation index, see [llms.txt](https://chapin666.gitbook.io/too-many-list-zh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chapin666.gitbook.io/too-many-list-zh/yi-ge-hai-hang-de-dan-lian-zhan/generic.md).

# Generic

我们已经用 Option 和 Box 触及了一些泛型。不过，到目前为止，我们已经设法避免了对任意元素声明任何实际上是泛型的新类型。

事实证明这真的很简单。现在让我们将所有类型设为泛型类型：

```rust
pub struct List<T> {
    head: Link<T>,
}

type Link<T> = Option<Box<Node<T>>>;

struct Node<T> {
    elem: T,
    next: Link<T>,
}
```

你只是把所有的东西都变得更尖锐一点，然后你的代码就突然变得通用了。当然，我们不能这样做，否则编译器会非常疯狂。

```rust
> cargo test

error[E0107]: wrong number of type arguments: expected 1, found 0
  --> src/second.rs:14:6
   |
14 | impl List {
   |      ^^^^ expected 1 type argument

error[E0107]: wrong number of type arguments: expected 1, found 0
  --> src/second.rs:36:15
   |
36 | impl Drop for List {
   |               ^^^^ expected 1 type argument

```

问题很明显：我们正在谈论 List 的事情，但是那不再是真实的了。 像Option 和 Box一样，我们现在总是要讨论 List\<Something> 。

但是我们在所有这些 impls 中使用的是什么？就像List一样，我们希望我们的实现能够与所有T一起使用。 因此，就像List一样，让我们的展示点很明确：

```rust
impl<T> List<T> {
    pub fn new() -> Self {
        List { head: None }
    }

    pub fn push(&mut self, elem: T) {
        let new_node = Box::new(Node {
            elem: elem,
            next: self.head.take(),
        });

        self.head = Some(new_node);
    }

    pub fn pop(&mut self) -> Option<T> {
        self.head.take().map(|node| {
            self.head = node.next;
            node.elem
        })
    }
}

impl<T> Drop for List<T> {
    fn drop(&mut self) {
        let mut cur_link = self.head.take();
        while let Some(mut boxed_node) = cur_link {
            cur_link = boxed_node.next.take();
        }
    }
}
```

就是这样！

```rust
> cargo test

     Running target/debug/lists-5c71138492ad4b4a

running 2 tests
test first::test::basics ... ok
test second::test::basics ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
```

现在，我们所有的代码对于T的任意值都是完全通用的。Rust很容易，我想对那些甚至没有改变的新事物说一句特别的话：

```rust
pub fn new() -> Self {
    List { head: None }
}
```

沐浴在自我的荣耀中，重构和复制粘贴编码的守护者。同样有趣的是，当我们构造一个 List 的实例时，我们不会写 List\<T> 。这个部分是基于我们从一个函数返回它，该函数需要一个 List\<T> 来推断的。

好吧，让我们继续全新的行为！
