From 2ace93d7a1533121bd34ae3281aec48455e4b91d Mon Sep 17 00:00:00 2001 From: Rustln Date: Sun, 13 Mar 2022 18:08:22 +0800 Subject: [PATCH] Add `transmute` examples --- src/basic/converse.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/basic/converse.md b/src/basic/converse.md index cc56abc5..6ff7a47c 100644 --- a/src/basic/converse.md +++ b/src/basic/converse.md @@ -283,3 +283,38 @@ impl Clone for Container { 你以为你之前凝视的是深渊吗?不,你凝视的只是深渊的大门。 `mem::transmute_copy` 才是真正的深渊,它比之前的还要更加危险和不安全。它从 `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<'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 行为!