2015-05-14 3 views
2

Часто мы не хотим, чтобы наша программа останавливалась из-за пределов, деление на 0 или подобные паники. Однако std::thread::catch_panic отмечен как неустойчивый. Мы могли бы написать ...Каков правильный способ захвата паники?

let result = Thread::scoped(move || { 
     make_a_division_for_ever() 
    }).join(); 
    if result.is_ok() { 
     println!("Finished OK"); 
    } 

Это правильный способ захвата паники (например, деление на 0 или за пределы)?

Полный пример ...

use std::thread::Thread; 

fn main() { 
    println!("Make divisions for ever"); 

    loop { 
     let result = Thread::scoped(move || { 
      make_a_division_for_ever() 
     }).join(); 
     if result.is_ok() { 
      println!("Finished OK"); 
     } 
     else { 
      println!("It CRASHED!!! restarting..."); 
     } 
    } 

} 

fn make_a_division_for_ever() { 
    loop { 
     println!("Enter divisor..."); 
     let line = std::io::stdin() 
       .read_line() 
       .ok() 
       .expect("error reading line"); 

     let divisor = line.trim() 
       .parse::<u32>() 
       .expect(" 
I coudn't parse your line as an string. I'm going to die 
I showed things closer than orion belt... 
     "); 

     println!("readed {}", divisor); 

     let dangerous = 1_000_000/divisor; 

     println!("DIV RESULT... {}", dangerous); 
    } 
} 
+3

Правильный способ не в первую очередь паниковать, а использовать правильную обработку ошибок, возвращать ошибки и подобные вещи. –

+0

Это отлично, но легко забыть о проверке целочисленного деления. легко получить панику за пределы доступа к элементам в векторе с помощью []. Это несколько примеров. Rust отлично справляется с компиляцией проверки, но это не заставляет нас проверять границы на векторном доступе (при использовании «[]» ни проверки силы на целочисленное деление. –

+3

Ошибка разделения или за пределами доступа являются логическими ошибками и должны быть Исправлено. Я понимаю, что может быть неудобно, что программа прерывается, но в C (++) она все равно сработает. – PEPP

ответ

7

ржавчины паникует не предназначены, чтобы быть пойманным в большинстве случаев. Нестабильная Rust предоставляет эту функциональность, но вы должны использовать ее только в том случае, если у вас действительно сложная ситуация (скажем, вы пишите тест-драйв для других программ Rust и должны подключаться к обработчику паники), где вы не можете пузыриться Ошибка.

В Руст, обработка ошибок осуществляется путем возврата Result<T,E> с (иногда Option<T>, кипящий их с try!(), и обращаться с ними с match

Наиболее панические методы имеют не-панические версии;., Например, проверяется версия divide - checked_div(), и вы можете использовать try!, чтобы вернуть ошибки в синтаксическом анализе строк.

+0

Мне нравится Resutl, Option и try !, но вы можете написать код, который несовместим с ним. Более того, в некоторых случаях легче писать код, создающий панику, чем код с ошибкой л. Пара примеров - это деление и за пределами вектора. Легче сделать разделение с оператором/или вызывать checked_div. Легче назвать my_vector [n], чем my_vector.as_slice.get (2). И компилятор не предупреждает вас. as_slice отмечен как неустойчивый ... Неустойчивый: ожидание в редакции RFC –

+1

Опять же, поскольку @PEEP указал в комментариях OP, если у вас есть непреднамеренное деление на ноль или за пределами доступа, у вас есть логическая ошибка в вашей программе , которые вы должны исправить. – thelink2012

+0

Абсолютно согласен. В C++ висячий указатель состояние гонки, доступ к некоторым данным и т. Д., Также являются ошибками программной логики, и они должны быть исправлены. Но мне не нравится, когда программа останавливается или падает из-за логической ошибки. –