Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Почему в Rust нет наследования?

// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

pub struct Id {
    pub id: u32
}

impl Id {
    // методы
}

// 🔨❌, в Rust нет наследования!
pub struct Data: Id {
    // Унаследованное поле "id"
    pub name: String,
}

impl Data {
    // методы, но также включает методы Id или, возможно, переопределения
    // этих методов.
}

// ✅
pub struct Data {
    pub id: Id,
    pub name: String,
}

impl Data {
    // Все методы data, которые не относятся к трейтам.
}

impl SomeTrait for Data {
    // Реализации трейтов в отдельных блоках impl.
}
  • У наследования есть ряд недостатков.

  • Разнородность по умолчанию:

    Наследование классов неявно позволяет использовать типы разных классов взаимозаменяемо, при этом нельзя явно указать конкретный тип или то, совпадает ли один тип с другим.

    Для таких операций, как равенство или сравнение, это допускает сравнение и проверку равенства, которые выбрасывают ошибку или иным образом вызывают панику.

  • Несколько источников истины о том, из чего состоит структура данных и как она себя ведёт:

    Поля типа скрыты иерархией наследования.

    Методы типа могут переопределять методы родительского типа или переопределяться дочерним типом. В сложных кодовых базах, которые поддерживают несколько сторон, трудно понять, каково поведение типа.

  • Динамическая диспетчеризация по умолчанию добавляет накладные расходы на поиск в vtable:

    Чтобы динамическая диспетчеризация работала, нужно место, где хранятся сведения о том, какие методы вызывать, и другая информация о типе, известная во время выполнения.

    Это хранилище и есть vtable значения. Вызовы методов требуют больше разыменований, чем вызов метода для типа, известного на этапе компиляции.