这是我在Rust的source code中发现的内容。我很难理解&mut *(self as *mut str as *mut [u8])
和self as *const str as *const u8
。
这是两步转换吗?首先转换为*mut str
或*const str
,然后转换为*mut [u8]
或*const u8
?
#[stable(feature = "str_mut_extras", since = "1.20.0")]
#[inline(always)]
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
&mut *(self as *mut str as *mut [u8])
}
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn as_ptr(&self) -> *const u8 {
self as *const str as *const u8
}
答案 0 :(得分:2)
在Rust中,as
运算符允许一次按一个步骤进行转换。
允许进行一些转换,例如:
&T
至*const T
,&mut T
至*mut T
,*mut T
至*mut U
(在T和U上附加一些条件),但是,即使您可以两次使用&mut T
到*mut T
到*mut U
到as
,也不能直接从&mut T
到{{1} };都是因为编译器和人员将很难找出中间步骤。
那么,这个转换顺序是什么?
*mut U
到&T
或*const T
变体。mut
的指针到指向str
的指针:典型的[u8]
到*const T
足以容纳*const U
和T
。 U
实际上具有与str
相同的表示形式,但是只有一小部分值有效(正确的UTF-8值)。有趣的是,一个是安全的,而不是另一个:
[u8]
均为str
,因此从[u8]
到*str
的转换始终是安全的。*[u8]
可以破坏&mut [u8]
内部的不变式,因此str
是as_bytes_mut
。