Зачем использовать Self вместо имени типа в конкретной реализации? - PullRequest
1 голос
/ 10 марта 2020

Документация для Add приводит следующий пример:

use std::ops::Add;

#[derive(Debug, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Self;

    fn add(self, other: Self) -> Self {
        Self {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

Почему автор документов использовал здесь Self вместо упоминания Point по имени ? Есть ли техническая разница или это просто для стилевых очков?

1 Ответ

5 голосов
/ 10 марта 2020

Существует две основные причины:

  • гибкость. Если вы решите изменить имя вашего типа, обновите его на одно место меньше.
  • краткость. Self короче MyType или SomeOtherType и особенно ThisTypeWithGenerics<'a, 'b, A, String>.

Есть ли техническая разница

Да и нет, в зависимости о том, как вы на это смотрите. Self - это тип, который был «полностью заполнен» в отношении дженериков. Это актуально в таких случаях:

struct Container<T>(T);

impl<T> Container<T> {
    fn replace<U>(self, new: U) -> Self {
        Container(new)
    }
}
error[E0308]: mismatched types
 --> src/lib.rs:5:19
  |
3 | impl<T> Container<T> {
  |      - expected type parameter
4 |     fn replace<U>(self, new: U) -> Self {
  |                - found type parameter
5 |         Container(new)
  |                   ^^^ expected type parameter `T`, found type parameter `U`
  |
  = note: expected type parameter `T`
             found type parameter `U`
  = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
  = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

Self - полный тип Container<T>, , а не конструктор типа Container. Это может вызвать трудных для понимания ошибок .

См. Также:

...