Наследование с точки зрения Rust
// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0
// Данные
pub struct Data {
id: usize,
name: String,
}
// Конкретное поведение
impl Data {
fn new(id: usize, name: impl Into<String>) -> Self {
Self { id, name: name.into() }
}
}
// Абстрактное поведение
trait Named {
fn name(&self) -> &str;
}
// Поведение экземпляра
impl Named for Data {
fn name(&self) -> &str {
&self.name
}
}
-
С точки зрения Rust, где наследования изначально не было, введение наследования выглядело бы как размывание границы между типами и трейтами.
-
Тип — это конкретный фрагмент данных и связанное с ним поведение.
Трейт — это абстрактное поведение, которое должен реализовать тип.
Класс — это сочетание данных, поведения и переопределений этого поведения.
-
С точки зрения Rust наследуемый класс выглядит как тип, который одновременно является трейтом.
-
Это не плюс: мы больше не можем рассуждать о конкретных типах.
-
Без возможности разделить эти два понятия трудно рассуждать об обобщённом поведении и конкретных деталях, потому что в ООП они тесно связаны друг с другом.
-
Удобство плоского доступа к полям и принцип DRY в определениях типов не стоят потери точности в разделении кода на поведение и данные.