rust中std::ptr::slice_from_raw_parts的实现原理是什么

7eumitmz  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(105)

我旧版本是1.64.0。
在文件“C:\Users.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs”中,我看到了std::ptr::slice_from_raw_parts的实现:

pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
    from_raw_parts(data.cast(), len)
}

在文件“C:\Users.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\metadata.rs”中,我看到了from_raw_parts的实现:

pub const fn from_raw_parts<T: ?Sized>(
    data_address: *const (),
    metadata: <T as Pointee>::Metadata,
) -> *const T {
    // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
    // and PtrComponents<T> have the same memory layouts. Only std can make this
    // guarantee.
    unsafe { PtrRepr { components: PtrComponents { data_address, metadata } }.const_ptr }
}

函数slice_from_raw_parts的返回类型是 *const [T],函数from_raw_parts的返回类型是 *const T。
为什么slice_from_raw_parts函数可以直接返回函数from_raw_parts的结果?
它们具有不同的返回类型。

c7rzv4ha

c7rzv4ha1#

这是两个不同的T
首先,slice_from_raw_parts本质上是:

pub const fn slice_from_raw_parts<T_slice_from>(data: *const T_slice_from, len: usize) -> *const [T_slice_from] {
    from_raw_parts::<T_from>(data.cast(), len)
}

请注意,T_fromT_slice_from不必相同。
关于from_raw_parts

pub const fn from_raw_parts<T_from: ?Sized>(
    data_address: *const (),
    metadata: <T_from as Pointee>::Metadata,
) -> *const T_from {
    // impl omitted
}

从这里你可以看到*const T_from必须等于(或强制等于)*const [T_slice_from],即T_from = [T_slice_from],这是可能的,因为from_raw_parts允许它的泛型类型是非Sized
为了使画面完整,-metadata:它在调用者中被输入为usize,在被调用者中被输入为<T_from as Pointee>::Metadata,即<[T_slice_from] as Pointee>::Metadata。没有明确的Pointee的实现文档,但是documentation for trait itself提到了切片的元数据是usize-这与我们的观察结果相匹配。

iibxawm4

iibxawm42#

from_raw_parts()T被推断为slice_from_raw_parts()[T],因此它们具有兼容的返回类型。

相关问题