Qqw*_*qwy 2 tuples data-representation rust transmute
我正在实施BTreeMap<K, V>
. 在此之上,我正在构建一个 BTreeSet,它是type MyBTreeSetContents<T> = MyBTreeMap<T, ()>
.
在内部,此 BTree 的叶节点包含一系列Vec<(K, V)>
值。对于 BTreeSet,这因此成为一个Vec<(K, ())>
.
我想提供一个对 BTreeSet 中值的引用的快速迭代器。产生 的迭代器&T
。但到目前为止,我能在不进行 transmute 的情况下得到的最好结果是生成&(T, ())
.
因此问题是:
K
、(K, )
和 的内存表示(K, ())
相同吗?(K, ())
和之间转换吗K
?Vec<(K, ())>
为 a吗Vec<K>
?如果有其他方法可以规避std::mem::transmute
all-together 的使用,那么我们当然也会非常感激!
不。就目前强制执行的内容而言,不能保证转变(T, ())
为。元组使用默认表示,除了The Rust ReferenceT
中所述之外,它不暗示任何有关布局的内容。只会保证布局兼容性。#[repr(transparent)]
然而,它可能会起作用并且最终可能得到保证。来自不安全代码指南中的结构体和元组:
一般来说,元数为
(T1..Tn)
N 的匿名元组类型的布局“就好像”有一个相应的元组结构.........
出于结构布局的目的,忽略1-ZST [1]字段。
特别是,如果除一个字段之外的所有字段都是 1-ZST,则该结构相当于单字段结构。换句话说,如果除一个字段之外的所有字段都是 1-ZST,则整个结构体具有与该字段相同的布局。
例如:
Run Code Online (Sandbox Code Playgroud)type Zst1 = (); struct S1(i32, Zst1); // same layout as i32
[1] 大小为零的类型称为零大小类型,缩写为“ZST”。本文档还使用“1-ZST”缩写,代表“一对齐零大小类型”,指对齐要求为 1 的零大小类型。
如果我对此的理解是正确的,(K, ())
则具有等效的布局K
,因此可以安全地进行转换。然而,这不会扩展到转化Vec<T>
为Rustonomicon 中的转化Vec<U>
中提到的:
即使同一泛型类型的不同实例也可能具有截然不同的布局。它们的字段的顺序可能相同,也可能不同
Vec<i32>
。Vec<u32>
不幸的是,你应该对此持保留态度。不安全代码指南旨在推荐unsafe
代码可以依赖的内容,但目前它仅将自己宣传为正在进行的工作,并且对语言规范的任何具体补充都将移至官方 Rust 参考。我说这“可能会起作用”,因为指南的一个方面是记录当前的行为。但到目前为止,参考文献中还没有提到这样的保证。