|
|
|
@ -283,3 +283,38 @@ impl<T> Clone for Container<T> {
|
|
|
|
|
你以为你之前凝视的是深渊吗?不,你凝视的只是深渊的大门。 `mem::transmute_copy<T, U>` 才是真正的深渊,它比之前的还要更加危险和不安全。它从 `T` 类型中拷贝出 `U` 类型所需的字节数,然后转换成 `U`。 `mem::transmute` 尚有大小检查,能保证两个数据的内存大小一致,现在这哥们干脆连这个也丢了,只不过 `U` 的尺寸若是比 `T` 大,会是一个未定义行为。
|
|
|
|
|
|
|
|
|
|
当然,你也可以通过原生指针转换和 `unions` (todo!)获得所有的这些功能,但是你将无法获得任何编译提示或者检查。原生指针转换和 `unions` 也不是魔法,无法逃避上面说的规则。
|
|
|
|
|
|
|
|
|
|
`transmute` 虽然危险,但作为一本工具书,知识当然要全面,下面列举两个有用的 `transmute` 应用场景 :)。
|
|
|
|
|
|
|
|
|
|
- 将原生指针变成函数指针:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
fn foo() -> i32 {
|
|
|
|
|
0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let pointer = foo as *const ();
|
|
|
|
|
let function = unsafe {
|
|
|
|
|
// 将原生指针转换为函数指针
|
|
|
|
|
std::mem::transmute::<*const (), fn() -> i32>(pointer)
|
|
|
|
|
};
|
|
|
|
|
assert_eq!(function(), 0);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- 延长生命周期,或者缩短一个静态生命周期寿命:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
struct R<'a>(&'a i32);
|
|
|
|
|
|
|
|
|
|
// 将 'b 生命周期延长至 'static 生命周期
|
|
|
|
|
unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
|
|
|
|
|
std::mem::transmute::<R<'b>, R<'static>>(r)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将 'static 生命周期缩短至 'c 生命周期
|
|
|
|
|
unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>) -> &'b mut R<'c> {
|
|
|
|
|
std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
以上例子非常先进!但是是非常不安全的 Rust 行为!
|
|
|
|
|