-
Option 和 Result 的處理 -
panic 的處理
Result<T, E>
)和不可恢復錯誤(
panic!
)提供了 Rust 特點的錯誤處理機制。
int
值,其中
0
表示成功,而負值表示錯誤。基於
setjmp
/
longjmp
的錯誤處理不屬於此節的討論範疇,若是有必要後面再作說明。
Option 和 Result 的處理
T: Sized
的
Option<&T>
和
Option<&mut T>
,代替顯式地進行無效性(nullity )檢查的指針。這是因爲 Rust 保證了可空指針優化(nullable pointer optimization),在 C 端能夠接受可空指針。C 端的
NULL
在 Rust 中被轉換爲
None
,而非空指針被封裝在
Some
中。
Result <T,E>
是用於返回和傳播錯誤的類型,其實質是一個枚舉,其中
Ok(T)
表示成功幷包含一個值,而
Err(E)
表示錯誤幷包含一個錯誤值。
-
簡單的返回 C 中經常使用的數值, 0
表示正確,-1
表示錯誤。 -
返回相似於 C 中的全局 errno
,建立一個線程局部變量(thread_local!
),並在每次收到Option
參數後進行檢查,返回相應的錯誤信息。 -
咱們能夠使用原始指針 std::ptr::null
和std::ptr::null_mut
來建立表示 C 端的空指針。
#[no_mangle]
pub unsafe extern "C" fn handle_option(x: c_float, y: c_float) -> i32 {
// The return value of the function is an option
let result = divide(x, y);
// Pattern match to retrieve the value
match result {
// The division was valid
Some(_) => 0,
// The division was invalid
None => -1,
}
}
#[no_mangle]
pub unsafe extern "C" fn handle_result(s: *const c_char) -> i32 {
if (s as *mut c_void).is_null() {
return -1;
}
let vb = CStr::from_ptr(s).to_str().unwrap();
let version = parse_version(vb);
match version {
Ok(_) => 0,
Err(_) => -1,
}
}
panic 的處理
panic
會致使未定義的行爲(Undefined Behavior,UB),咱們還須要確保咱們的 FFI 綁定是異常安全(Exception Safety)的。也就是說若是 Rust 導出庫的代碼可能會出現
panic
,則須要有個處理機制。在 FFI 綁定時咱們能夠使用
catch_unwind
將其包含在 Rust 中,從而不跨越 FFI 邊界。
use std::panic::catch_unwind;
fn may_panic() {
if rand::random() {
panic!("panic happens");
}
}
#[no_mangle]
pub unsafe extern "C" fn no_panic() -> i32 {
let result = catch_unwind(may_panic);
match result {
Ok(_) => 0,
Err(_) => -1,
}
}
catch_unwind
只能捕獲 Rust 中的展開(
unwinding
)
panic
,而不能處理 Rust 中的終止程序(
abort
)
panic
。
當出現 panic
時,Rust 程序默認會開始展開,這意味着 Rust 會回溯棧並清理它遇到的每個函數的數據,不過這個回溯並清理的過程有不少工做。另外一種選擇是直接終止,這會不清理數據就退出程序。那麼程序所使用的內存須要由操做系統來清理。經過在 Cargo.toml 的[profile]
部分增長panic = 'abort'
,程序在panic
時會由展開切換爲終止。
-
https://s3.amazonaws.com/temp.michaelfbryan.com/errors/index.html -
https://michael-f-bryan.github.io/rust-ffi-guide/errors/index.html -
https://doc.rust-lang.org/nomicon/repr-rust.html
本文分享自微信公衆號 - Rust語言中文社區(rust-china)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。html