Rust
Паники и разматывания
Поиск…
Вступление
panic!
макрос может вызываться для быстрого выхода (часто сравнивается, но тонко отличается от исключения на других языках). Правильная обработка ошибок должна включать в себя типы Result
, хотя в этом разделе будет обсуждаться только panic!
и его концепций.
замечания
Паники не всегда вызывают утечки памяти или утечки других ресурсов. На самом деле, паники обычно сохраняют инварианты RAII, запуская деструкторы (Drop-реализаций) структур при раскручивании стека. Однако, если во время этого процесса возникает вторая паника, программа просто прерывается; в этот момент инвариантные гарантии RAII являются недействительными.
Старайтесь не паниковать
В Rust есть два основных метода, указывающих на то, что в программе что-то пошло не так: функция, возвращающая ( потенциально настраиваемый ) Err(E)
из типа Result<T, E>
и panic!
,
Паника не является альтернативой исключениям, которые обычно встречаются на других языках. В Ржавчине паника указывает на то, что что-то пошло не так, и что она не может продолжаться. Вот пример из источника Vec
для push
:
pub fn push(&mut self, value: T) {
// This will panic or abort if we would allocate > isize::MAX bytes
// or if the length increment would overflow for zero-sized types.
if self.len == self.buf.cap() {
self.buf.double();
}
...
}
Если у нас заканчивается память, Rust может не так много сделать, поэтому она будет либо паниковать (поведение по умолчанию), либо прерывать (что необходимо установить с помощью флага компиляции).
Паника будет разворачивать стек, запускать деструкторы и обеспечивать очистку памяти. Abort не делает этого и полагается на ОС для правильной очистки.
Попробуйте запустить следующую программу как обычно, так и с помощью
[profile.dev]
panic = "abort"
в вашем Cargo.toml
.
// main.rs
struct Foo(i32);
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping {:?}!", self.0);
}
}
fn main() {
let foo = Foo(1);
panic!("Aaaaaaahhhhh!");
}