如何通过多个“ as”强制转换转换原始str?

时间:2019-01-22 21:23:41

标签: pointers rust type-conversion

这是我在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
}

1 个答案:

答案 0 :(得分:2)

在Rust中,as运算符允许一次按一个步骤进行转换。

允许进行一些转换,例如:

  • &T*const T
  • &mut T*mut T
  • *mut T*mut U(在T和U上附加一些条件),
  • ...

但是,即使您可以两次使用&mut T*mut T*mut Uas,也不能直接从&mut T到{{1} };都是因为编译器和人员将很难找出中间步骤。


那么,这个转换顺序是什么?

  • 从引用到指针:典型的*mut U&T*const T变体。
  • 从指向mut的指针到指向str的指针:典型的[u8]*const T足以容纳*const UTU实际上具有与str相同的表示形式,但是只有一小部分值有效(正确的UTF-8值)。

有趣的是,一个是安全的,而不是另一个:

  • 由于所有[u8]均为str,因此从[u8]*str的转换始终是安全的。
  • 但是,公开*[u8]可以破坏&mut [u8]内部的不变式,因此stras_bytes_mut