gpt4 book ai didi

rust - Deref struct to tuple 需要移动

转载 作者:行者123 更新时间:2023-11-29 08:18:40 25 4
gpt4 key购买 nike

我在 Rust 中编写一个 Vector 类只是为了好玩,我认为能够为它实现 Deref 会很好,就像访问元组引用一样访问它。例如,Vec2<f32>可以取消引用为 &(f32, f32) .我想到了这个:

pub struct Vec2<T> {
pub x: T,
pub y: T
}

impl<T> Deref for Vec2<T> {
type Target = (T, T);

fn deref(&self) -> &(T, T) {
&(self.x, self.y)
}
}

但是,由于编译器想要创建元组然后引用它,它会尝试移出结构。如果我使用 type Target = (&T, &T)然后返回 &(&T, &T)我必须使用明确的生命周期说明符,但我没有,因为我无法访问 self 生命周期。

现在我的问题是:有没有办法在不复制值的情况下做到这一点?由于我经常使用小型类型,因此我可能不会真正使用 Deref,但我想 DerefMut 可能会变得有用。

最佳答案

总结

现在,没有办法做到这一点!至少在不使用 unsafe 的情况下不行! .


为什么?

考虑返回类型 -> &Foo .这意味着该函数返回对 Foo 的引用已经住在某个地方。特别是,如果你有 fn deref(&self) -> &Foo这意味着 Foo至少活到self ,因为生命周期省略开始并将其转换为 fn deref<'a>(&'a self) -> &'a Foo .

现在,(T, T)是一种类似于 Foo 的类型.所以fn deref(&self) -> &(T, T)意味着您返回对 T 的元组的引用它已经住在某个地方。但是没有这样的元组!您可以在函数中创建一个元组,但这不会存在足够长的时间。同样,如果你说 -> &(&T, &T)您说您返回了对已经存在于某处的元组(对 T 的引用)的引用。但同样:你没有一个已经存在于某处的元组。

所以特征 Deref要求您返回对已经与 self 中的内容完全相同的内容的引用.所以有了这个,就不可能做你想做的事。

不安全

您可以使用不安全函数 mem::transmute() .毕竟,像您这样的结构和元组应该具有完全相同的内存布局,对吧?

是也不是。两种内存布局可能是相同的,但 Rust 不保证! Rust 可以自由地重新排序字段和添加填充字节。虽然我怀疑结构、元组结构和元组的内存布局完全相同,但我找不到相关资料。因此,如果规范中没有这些信息,转换在技术上是不安全的。

future

在未来,HKT 或更确切地说是通用关联类型可以解决这个问题。也就是说,它们不会直接解决您的问题,而是使用 GAT,如 this RFC 中定义的那样。 ,可以重新定义 Deref特征。即:

trait Deref {
type Target<'a>;
fn deref(&self) -> Self::Target<'a>;
}

现在我们被迫将生命周期放在“最外层”。有了这个,我们可以让类型实现 Deref决定。在那种情况下你可以写:

impl<T> Deref for Vec2<T> {
type Target<'a> = (&'a T, &'a T);

fn deref(&self) -> Self::Target {
(&self.x, &self.y)
}
}

这样生命周期就“在里面”了。

但是 GAT 甚至还没有实现,所以还需要一些时间。此外,尚不清楚标准库何时/如何/是否以向后不兼容的方式更改,这将允许更改 Deref .

关于rust - Deref struct to tuple 需要移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46081831/

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