Структура Vec
выглядит примерно так: this [1] :
pub struct Vec<T> {
ptr: *mut T,
capacity: usize,
len: usize,
}
Идея состоит в том, что ptr
указывает на выделенный блокпамять размером capacity
.Если размер Vec
должен быть больше, чем capacity
, то выделяется новая память.Неиспользованная часть выделенной памяти неинициализирована и может содержать произвольные данные.
Когда вы вызываете изменяющиеся методы на Vec
, например push
или pop
, они тщательно управляют внутренним состоянием Vec
.увеличьте емкость при необходимости и убедитесь, что удаленные элементы правильно отброшены.
Если len
было открытым полем, любой код с принадлежащим Vec
или изменяемой ссылкой на него может быть установленlen
на любое значение.Установите его выше, чем должно быть, и вы сможете читать из неинициализированной памяти, вызывая Неопределенное поведение .Установите его ниже, и вы будете эффективно удалять элементы, не удаляя их должным образом.
В некоторых других языках программирования (например, JavaScript) API для массивов или векторов, в частности, позволяет изменять размер, устанавливая свойство length
,Весьма разумно думать, что программист, привыкший к такому подходу, может сделать это случайно в Rust.
Сохранение всех полей закрытыми и использование метода получения для len()
позволяет Vec
защитить изменчивостьего внутренние компоненты обеспечивают надежную память и предотвращают случайное совершение пользователями плохих действий.
[1] На практике над этой структурой данных построены уровни абстракции, поэтому выглядит немного иначе .