为什么 `std::ptr::null` 不能用于未定义大小的类型?

Pie*_*ine 5 pointers rust

据我了解,在 Rust 中创建空指针的标准(仅?)方法是std::ptr::null.

但是,该函数声明如下。

pub const fn null<T>() -> *const T
Run Code Online (Sandbox Code Playgroud)

在此声明中,T隐式假定具有固定大小(否则,它将是T: ?Sized)。因此,无法与*const str或一起使用此功能*const [u32]在操场上测试一下

是否有充分的理由排除未调整大小的类型?想要创建一个 null 有*const str什么问题?

tre*_*tcl 6

指向 unsized 类型的指针是一个包含两个组件的胖指针:指针和类型元数据(切片的长度和 trait 对象的 vtable 指针;将来,Rust 可能会允许其他类型的元数据)。null仅暗示指针部分的值;另一个值没有明显的选择。(您可能认为 0 对于空切片指针的长度是显而易见的,并且我可以看到参数,但是如果指针为空,则几乎不重要有多少东西;无论如何您都不能取消引用它,因此使大小0 不是确保安全所必需的。)

无法创建指向 trait 对象的空指针,但从 Rust 1.42 开始,您可以使用ptr::slice_from_raw_parts创建指向切片的空指针。假设切片的长度为 0:

use std::ptr;
fn main() {
    let p: *const [u32] = ptr::slice_from_raw_parts(ptr::null(), 0);
    println!("{:?}", p);
}
Run Code Online (Sandbox Code Playgroud)

没有等效的函数str,但您可以通过创建一个 null*const [u8]并使用as.

此函数(或相关的slice_from_raw_parts_mut)是创建指向切片的空指针的唯一方法。获取原始指针的常用方法是通过转换引用,但引用可能永远不会为空。

  • 有趣的是,“slice_from_raw_parts”是安全的——原因是它几乎无法使用,因为函数采用引用而不是指针,并且从指针到引用需要“不安全”。 (2认同)