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);

【问题讨论】:

我不确定我是否理解。既然firstsecond 只是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)有相反的含义吗?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL-left join _20160928

Hive - 每个日期选择不同的唯一 ID,无需创建外部表或使用 JOINS

00_Rust安装及Hello World

CROSS JOIN 和 INNER JOIN 有啥区别[关闭]

Rust 备忘清单_开发速查表分享

网鼎杯 fakebook