3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Rust] Vec<[T; N]>をVec<T>に変換する

Last updated at Posted at 2020-08-02

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)
    }
}
  1. この手の記事は噂のQiitaの「質問」機能を使うべきなんでしょうか?

3
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?