问题
As I understand, the standard (only?) way to make a null pointer in Rust is std::ptr::null.
However, that function is declared as follows.
pub const fn null<T>() -> *const T
In this declaration, T is implicitly assumed to have fixed size (otherwise, it would be T: ?Sized). As a consequence, it is impossible to use this function with *const str or *const [u32] for example. test it in the playground
Is there a good reason for excluding unsized types? What's wrong with wanting to create a null *const str?
回答1:
A pointer to an unsized type is a fat pointer with two components: the pointer and the type metadata (a length for slices, and a vtable pointer for trait objects; in the future, Rust may allow other kinds of metadata). null only implies a value for the pointer part; there's no obvious choice for the other value. (You might think 0 is obvious for the length of a null slice pointer, and I can see the argument, but if the pointer is null it hardly matters how many things are there; you can't dereference it anyway, so making the size 0 is not necessary to ensure safety.)
There is no way to create a null pointer to a trait object, but as of Rust 1.42, you can use ptr::slice_from_raw_parts to create a null pointer to a slice. Let's suppose the length of the slice is 0:
use std::ptr;
fn main() {
let p: *const [u32] = ptr::slice_from_raw_parts(ptr::null(), 0);
println!("{:?}", p);
}
There is no equivalent function for str, but you could make one by creating a null *const [u8] and casting it with as.
This function (or the related slice_from_raw_parts_mut) is the only way to soundly create a null pointer to a slice. The usual way to get a raw pointer is by casting a reference, but references may never be null.
来源:https://stackoverflow.com/questions/59426821/why-is-stdptrnull-not-usable-with-unsized-types