Rust:split_at_mut(即 join_mut)有相反的含义吗?
Posted
技术标签:
【中文标题】Rust:split_at_mut(即 join_mut)有相反的含义吗?【英文标题】:Rust: Is there an opposite for split_at_mut (i.e. join_mut)? 【发布时间】:2016-07-22 18:52:57 【问题描述】:有一个非常好的 split_at_mut 函数,它可以将 1 个切片变成 2 个切片... 有没有办法撤消该操作,以便我可以再次回到原来的数组——假设我知道它们在内存中是连续的(因为我只是拆分它们)
问题是:有没有类似于 join_mut 这样的东西:
fn main()
let mut item : [u8;32] = [0u8;32];
let (mut first, mut second) = item[..].split_at_mut(16);
first[0] = 4;
second[0] = 8;
let mut x = first.join_mut(first, second); // <-- compile error
assert_eq(x[16], 8);
【问题讨论】:
我不确定我是否理解。既然first
和second
只是item
的一部分,为什么不使用item
本身而不是尝试加入它们呢?将x
替换为item
中的assert_eq!(item[16], 8);
将通过测试(假设您归还了借来的切片)或者这只是您实际尝试做的简化?
在这个简化的例子中是合理的。但是让我们假设您正在制作某种分配器,并且您将 2 个未连接的切片返回给客户端并且它们都被释放了,因此您希望能够将它们连接成更大的切片。在这种情况下,您肯定会忘记每个切片的来源,也不会知道原始项目,因为它通过 split_at_mut 借用了数十个其他切片
有问题的确切情况在这里:github.com/dropbox/rust-alloc-no-stdlib/blob/master/src/… in free_cell 其中 &'a mut 切片被返回到系统,很高兴看看它们是否可以与其他 free'd 重新组合切片以统一它们
【参考方案1】:
标准库中没有这样的函数,可能是因为它是一个相当小众的情况,通常可以通过使用在第一种情况下拆分的切片来解决。
话虽这么说,但有一点不安全是可以实现的。
fn join_mut<'a, T>(first: &'a mut [T], second: &'a mut [T]) -> Option<&'a mut [T]>
let fl = first.len();
if first[fl..].as_mut_ptr() == second.as_mut_ptr()
unsafe
Some(::std::slice::from_raw_parts_mut(first.as_mut_ptr(), fl + second.len()))
else
None
Playground
【讨论】:
对于这些实际上来自同一片的情况,这段代码对我来说非常有意义。但是,在 C++ 中,比较来自不同数组的指针的相等性是未定义的行为(我认为是为了补偿分段架构)。这是 Rust 中定义的行为吗? 我不知道在某些情况下比较 C++ 中的指针可能是未定义的行为。不确定 Rust 是如何定义它的,所以恐怕需要更有知识的人来回答这个问题。这对我来说似乎真的违反直觉,但在这种情况下可能是我的代码实际上包含未定义的行为。 @hellcatv 我发现这个问题***.com/questions/4909766/… 说它未指定 等但 == 和 != 返回一个定义的结果,所以我相信至少对于 C++ 没有检查两个指针是否相等时的未定义行为。可能 Rust 也没有明确说明这一点。以上是关于Rust:split_at_mut(即 join_mut)有相反的含义吗?的主要内容,如果未能解决你的问题,请参考以下文章
Hive - 每个日期选择不同的唯一 ID,无需创建外部表或使用 JOINS