比较定长数组

7

编辑注:这个问题是在 Rust 1.0 之前提出的,使用的语法已不再有效。此外,该问题中的特定问题在 Rust 1.0 中也不再存在。

有一个结构体,它只包含一个固定宽度的字节数组字段。人们可能会认为为其实现 std::cmp 的 trait 是很简单的,但是自动派生并不能起作用:

#[deriving(Eq)]
pub struct ID {
    bytes: [u8, ..::constants::ID_SIZE]
}

src/id.rs:3:5: 3:40 error: mismatched types: expected `&&[u8]` but found `&[u8, .. 20]` ([] storage differs: expected `&` but found `20`)
src/id.rs:3     bytes: [u8, ..::constants::ID_SIZE]
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of #[deriving]
src/id.rs:1:1: 2:4 note: expansion site

文档建议Eq适用于&[]~[],而不适用于固定宽度数组。手动强制转换为&[]也不起作用:

impl Eq for ID {
    fn eq(&self, other: &ID) -> bool {
        (&self.bytes).eq(&other.bytes)
    }
}

src/id.rs:7:26: 7:38 error: mismatched types: expected `&&[u8, .. 20]` but found `&[u8, .. 20]` (expected &-ptr but found vector)
src/id.rs:7         (&self.bytes).eq(&other.bytes)
                                     ^~~~~~~~~~~~
src/id.rs:7:9: 7:39 error: failed to find an implementation of trait std::cmp::Eq for [u8, .. 20]
src/id.rs:7         (&self.bytes).eq(&other.bytes)
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这在 Rust 参考手册中可能会解释:

生成确定大小的向量的表达式不能在期望无限大小的向量的上下文中进行评估;必须将确定大小的向量内容复制到一个不同的无限大小的向量中。

动机不清楚,但我猜这与存储长度有关。

无论如何,是否可以使用 &[] 的实现来比较两个固定长度的数组,而不需要复制?

1个回答

8

文档建议使用 &[] 和 ~[] 实现 Eq,而不是固定宽度数组。

是的,这是因为 [T,..2] 是与 [T,..3] 不同的类型。

无论如何,是否可能使用 &[] 的实现而不进行复制来比较两个固定长度的数组?

很容易实现。

impl Eq for ID {
    fn eq(&self, other: &ID) -> bool {
        self.bytes.iter().zip(other.bytes.iter()).all(|(a,b)| a == b) 
    }
}

这个解决方案没有使用&[]的实现。无论如何还是谢谢。 - Michael Ivko
你也可以使用self.bytes.as_slice() == other.bytes.as_slice(),但据我所知,目前每个切片都会导致一次分配,因此在这种情况下应该避免使用,直到有所改变。 - A.B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接