# 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> 来推断的。

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chapin666.gitbook.io/too-many-list-zh/yi-ge-hai-hang-de-dan-lian-zhan/generic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
