gpt4 book ai didi

rust - 将类型替换为 Wrapper

转载 作者:行者123 更新时间:2023-11-29 08:06:21 24 4
gpt4 key购买 nike

我有一个值的引用,我想将其替换为对包装该值的包装器结构的引用。

例子:

struct Wrapper<T>(T);

let num = 123;
let x: &i32 = &num;
let wrapped: &Wrapper<i32> = .. // some conversion

这可能吗? (首选安全解决方案,但不是必需的。)

最佳答案

让您的示例代码正常工作很容易:

let wrapped: &Wrapper<i32> = &Wrapper(*x);    // type annotation optional

来自 C++,你可能会认为这是非常不安全的,因为我们引用了一个临时的(左边的表达式)。但在这种情况下,Rust 只是将这个临时表达式的结果保存在堆栈中。上面的代码等同于:

let hidden = Wrapper(*x);
let wrapped: &Wrapper = &hidden;

到目前为止一切顺利,但是当我们想要返回这个引用时出现了问题。例如:

fn wrap<T>(t: &T) -> &Wrapped<T> {
&Wrapped(*t)
}

我们这里有两个问题。首先,我们不能搬出t (它只是借来的;它只在上面的代码中起作用,因为 i32Copy )第二,我们不能返回对局部变量(为我们创建的 hidden )的引用。


要解决这个问题,您可以使用 unsafe函数 std::mem::transmute() .这只是将任何类型解释为另一种任何其他类型。

但是等等! unsafe {}意思是“编译器,相信我!”,但我们应该相信自己吗?我们作为程序员必须保证 Wrapped<T>T具有完全相同的数据布局。那么:是这样吗?

这在大多数平台上可能都是正确的,但我非常怀疑我们能否保证这一点!当涉及到结构(和单元结构)的数据布局时,Rust 似乎没有太多 promise 。它可能会重新排序字段(在这种情况下并不重要)并且可能会添加填充。 repr(Rust) chapter of the Rustonomicon 中有更多相关信息.


总结:类似wrap() 的函数不能安全地实现。因此,应避免使用包含此类功能的 API。

关于rust - 将类型替换为 Wrapper<Type>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41343615/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com