Vec<[T; N]>
を Vec<T>
に効率的に変換するコードが必要だったのですが, うまくできず焦ってひねり出しました. いささか自信がないのですが, これでいいんでしょうか. safe にできる気がするのですが1.
※unsafe コードです. ご利用は自己責任で.
PlayGround: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ac728a798c07d9f7b4f69bd19e5db89c
const N: usize = 4;
fn into_raw_vec<T>(v: Vec<[T; N]>) -> Vec<T> {
let mut v = std::mem::ManuallyDrop::new(v);
let p = v.as_mut_ptr() as *mut T;
let len = v.len() * N;
let cap = v.capacity() * N;
unsafe {
Vec::from_raw_parts(p, len, cap)
}
}
fn main() {
let original: Vec<[i32; N]> = (0..8).map(|i| [i; N]).collect();
println!("{:?}", &original);
let raw_vec: Vec<i32> = into_raw_vec(original);
println!("{:?}", raw_vec);
}
参考文献
追記 2020-08-06
@YoshiTheChinchilla さんと @kobae964 さんに有用なコメントを頂いたのでコメント欄もご覧ください. オーバーフローチェックも行うとこんな感じでしょうか.
fn into_raw_vec<T>(v: Vec<[T; N]>) -> Vec<T> {
let mut v = std::mem::ManuallyDrop::new(v);
let p = v.as_mut_ptr() as *mut T;
let len = v.len().checked_mul(N).unwrap();
let cap = v.capacity().checked_mul(N).unwrap();
unsafe {
Vec::from_raw_parts(p, len, cap)
}
}
-
この手の記事は噂のQiitaの「質問」機能を使うべきなんでしょうか? ↩