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

Паттерн newtype

Newtype — обёртка вокруг существующего типа, часто примитивного:

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

/// Уникальный идентификатор пользователя, реализованный как newtype вокруг `u64`.
pub struct UserId(u64);

В отличие от псевдонимов типов, newtype не взаимозаменяем с оборачиваемым типом:

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

pub struct UserId(u64);

fn needs_user(user: UserId) {
    // ...
}

fn main() {
    needs_user(1); // 🛠️❌
}

Компилятор Rust также не позволит использовать методы или операторы, определённые для базового типа:

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

pub struct UserId(u64);

fn main() {
    assert_ne!(UserId(1), UserId(2)); // 🛠️❌
}
This slide and its sub-slides should take about 20 minutes.
  • Студенты должны были встретить паттерн newtype на курсе «Основы», когда изучали кортежные структуры.

  • Запустите пример, чтобы показать студентам сообщение об ошибке компилятора.

  • Измените пример так, чтобы использовать псевдоним типа вместо newtype, например type MessageId = u64. Изменённый пример должен компилироваться, что подчеркнёт различия между двумя подходами.

  • Подчеркните, что newtype по умолчанию не имеет связанного с ним поведения. Нужно сознательно решать, какие методы и операторы базового типа вы готовы переадресовывать. В нашем примере UserId разумно разрешить сравнение UserId, но не имеет смысла разрешать арифметические операции вроде сложения или вычитания.