rust - 限制为 const N 时的 mem::transmute 错误
问题描述
我不明白为什么编译器不让这个例子编译:
use std::mem::{self, MaybeUninit};
fn foo<const N: usize>() -> [u32; N] {
let mut res: [MaybeUninit<u32>; N] = unsafe { MaybeUninit::uninit().assume_init() };
for elem in &mut res[..] {
unsafe { elem.as_mut_ptr().write(0) };
}
unsafe { mem::transmute::<[MaybeUninit<u32>; N], [u32; N]>(res) }
}
Compiling playground v0.0.1 (/playground)
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> src/lib.rs:11:14
|
11 | unsafe { mem::transmute::<[MaybeUninit<u32>; N], [u32; N]>(res) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: source type: `[MaybeUninit<u32>; N]` (this type does not have a fixed size)
= note: target type: `[u32; N]` (this type does not have a fixed size)
error: aborting due to previous error
很明显,N 对于结果和输入数组都是相同的。有没有办法做到这一点?
解决方案
这是编译器的限制。它们的大小确实相同,但编译器无法看到(还没有?)。
您可以使用原始指针转换来实现这一点,因为编译器不会检查大小是否相等:
use std::mem::{self, MaybeUninit};
fn foo<const N: usize>() -> [u32; N] {
let mut res: [MaybeUninit<u32>; N] = unsafe { MaybeUninit::uninit().assume_init() };
for elem in &mut res[..] {
unsafe { elem.as_mut_ptr().write(0) };
}
unsafe { *(&res as *const [MaybeUninit<u32>; N] as *const [u32;N] ) }
}
或者有array_assume_init
,但仍然不稳定,所以只在夜间使用。
#![feature(maybe_uninit_array_assume_init)]
use std::mem::{self, MaybeUninit};
fn foo<const N: usize>() -> [u32; N] {
let mut res: [MaybeUninit<u32>; N] = unsafe { MaybeUninit::uninit().assume_init() };
for elem in &mut res[..] {
unsafe { elem.as_mut_ptr().write(0) };
}
unsafe { MaybeUninit::array_assume_init(res) }
}
推荐阅读
- python - 获取体内硒
- docker - 如何通过 Kubernetes 拉取托管在 Google Container Registry 上的 docker 镜像(桌面版 docker 中包含的 kubernetes)
- c++ - Boost Asio 和 Beast mulitpart/form-data 从 streambuf 保存二进制文件
- connection - Telnet 问题:连接到 localhost... 连接失败
- c++ - g ++编译的程序集会导致无限循环?
- javascript - Bootstrap 3.3 折叠适用于除第一个元素之外的每个相同元素
- php - 页面链接多个在 php 搜索分页中不起作用
- java - 多播线程在 Android 8.0 (Oreo) 中突然停止
- javascript - jquery每个函数(key,value)结果只返回最后一个key和value
- html - 如何全宽到内联按钮?