String
和 Vec<u8>
具有相同的内存布局,尽管不能保证这一点。
into_bytes
方法返回 Vec<u8>
。
有没有一种好的方法可以从
Arc<String>
转换为 Arc<Vec<u8>>
而不为新的 Arc
分配任何内存?我们可以断言弧引用计数为1。我不介意使用unsafe。我也不介意断言它们具有相同的大小/在这种情况下回落到分配。这可能吗?
String::as_mut_vec
到达那里:
use static_assertions::{assert_eq_align, assert_eq_size};
use std::sync::Arc;
const _: () = {
assert_eq_align!(String, Vec<u8>);
assert_eq_size!(String, Vec<u8>);
};
pub unsafe fn convert(mut arc: Arc<String>) -> Arc<Vec<u8>> {
Arc::get_mut(&mut arc).unwrap();
let raw_string = Arc::into_raw(arc).cast_mut();
// SAFETY: `get_mut...unwrap` above ensured that we have exclusive access
let ref_string = unsafe { &mut *raw_string };
// SAFETY: We do not modify the `Vec` before dropping `ref_string`
let raw_vec = unsafe { ref_string.as_mut_vec() } as *const Vec<u8>;
let _ = ref_string;
assert_eq!(raw_vec.cast(), raw_string);
// SAFETY: assertion above ensures that `raw_vec` points to the same memory
// as `raw_string`, and static assertions above guarantee that `String`
// has the same size and alignment as `Vec<u8>`
unsafe { Arc::from_raw(raw_vec) }
}