Constructors

default() и new()

Конструкторы в Rust являются соглашением. Можно использовать другие имена, но принято использовать два основных: default и new

Отличия

Представим на примере создания персонажа в компьютерной игре.

default() — это как выбор кнопки «Быстрый старт» или «Случайный персонаж»:

  • Вы получаете персонажа со стандартными/случайными характеристиками;
  • Вы ничего не выбираете. Это одинаково для всех, кто выбирает этот вариант;
  • Идеально, когда вы просто хотите быстро начать.

new() — это как создатель «Пользовательского персонажа»:

  • ВЫ решаете начальные характеристики;
  • Вы можете передавать определенные значения;
  • Каждый персонаж может быть разным;
  • Идеально, когда вы хотите контролировать создание.

Пример с default:

pub struct SmartThermometer {
    current_temperature: f32,
}

impl Default for SmartThermometer {
    fn default() -> Self {
        SmartThermometer {
            current_temperature: rand::rng().random_range(-30.0..50.0),
        }
    }
}

Проблема конструктора в том, что он не привязан к контексту. Что именно определяется - температура морозильника? Тёплого солнечного дня? Температура тела больного пациента? - для default() абсолютно всё равно.

Добавка контекста с new:

impl SmartThermometer {
    // определяем начальную Т
    pub fn new(initial_temp: f32) -> Self {
        SmartThermometer {
            current_temperature: initial_temp,
        }
    }
    
    // можно оставить default(), когда надо начальное 36.6
}

Совместное использование

Внутри default() можно вызвать new() для предпочитаемых значений:

impl Default for SmartThermometer {
    fn default() -> Self {
        Self::new(36.6) // использует внутри new()
    }
}