Unsafe Rust - The Rust Programming Language 日本語版
unsafe は契約
コンパイラが安全性を保証できないときは unsafe を使ってコードを書いた人が安全性を保証する。
関数自体は通常の Rust だが、関数内部で unsafe が必要な例
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
let len = slice.len();
let ptr = slice.as_mut_ptr();
assert!(mid <= len);
unsafe {
(slice::from_raw_parts_mut(ptr, mid),
slice::from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
}
}
↓ このように実装すると、mut 参照を2つ取ることになってエラーになる。
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
let len = slice.len();
assert!(mid <= len);
(&mut slice[..mid],
&mut slice[mid..])
}
実際には参照は被っていないため、問題ないのだが、コンパイラにはわからないのでコンパイルエラーになる。そのため、最初の実装のように、生ポインタを使った実装をし、実装者が安全性を保証する形を取る。
unsafe superpowers