【问题标题】:Proper way to build an array from a slice? [duplicate]从切片构建数组的正确方法? [复制]
【发布时间】:2015-06-16 21:22:43
【问题描述】:

好的,这似乎有点傻,但是我很难找到一个函数来从切片的内容中返回一个静态大小的数组。

关于数组和切片的 Rust Book 部分对此只字未提。 (它确实展示了如何从数组中获取切片,但我想换一种方式。)我还检查了 std::slicestd::array 的文档,但如果它在那里,我没有看到它。

当然可以选择逐个写出每个元素,但这似乎很荒谬。现在,我最终编写了一个 python 单线来为我做这件事。

", ".join(["k[{}]".format(i) for i in range(32)])

所以我最终得到了这个:

use db_key::Key;

#[derive(Clone)]
pub struct Sha256{
    bits : [u8;32]
}

impl Key for Sha256 {
    fn from_u8(k: &[u8]) -> Self {
        Sha256{bits:
               // FIXME: This is dumb.
               [ k[0], k[1], k[2], k[3], k[4], k[5], k[6], k[7], k[8], k[9], k[10], k[11], k[12], k[13], k[14], k[15], k[16], k[17], k[18], k[19], k[20], k[21], k[22], k[23], k[24], k[25], k[26], k[27], k[28], k[29], k[30], k[31] ]
        }
    }
    fn as_slice<T, F: Fn(&[u8]) -> T>(&self, f: F) -> T {
        f(&self.bits)
    }
}

我想知道是否有合适的方法,比如k.to_array(32) 或类似的东西。

而且,是的,我意识到上述代码可能会因越界访问而失败。我不确定db_key::Key 对无效输入的期望。

编辑:

Is there a good way to convert a Vec to an array? 类似但不太通用。对这个问题的一个好的答案可能也是对这个问题的一个很好的答案,加上从vec 中提取一个片段,这可以高效而简洁地完成。我也不认为“为您关心的每种尺寸编写单独的转换函数”是一个合适的解决方案。

How to get a slice as a static array in rust? 也类似,但公认的答案是我已经独立提出的 hack。

【问题讨论】:

    标签: arrays rust slice


    【解决方案1】:

    您可以使用循环以直接(但可能令人失望)的方式解决它:

    let input = b"abcdef";
    let mut array = [0u8; 32];
    for (x, y) in input.iter().zip(array.iter_mut()) {
        *y = *x;
    }
    

    我们可以使用函数进行运行时大小检查,并将切片转换为对固定大小数组的引用。

    Libstd 没有提供足够的特征来可靠地检查输入和输出类型是否匹配,但理论上我们可以自己开发(对于有限数量的数组类型)。无论哪种方式,演员表看起来像这样,U 是您指定的任意数组类型。

    /// Return a reference to a fixed size array from a slice.
    ///
    /// Return **Some(array)** if the dimensions match, **None** otherwise.
    ///
    /// **Note:** Unsafe because we can't check if the **U** type is really an array.
    pub unsafe fn as_array<T, U>(xs: &[T]) -> Option<&U> where
        U: AsRef<[T]>,
    {
        let sz = std::mem::size_of::<U>();
        let input_sz = xs.len() * std::mem::size_of::<T>();
    
        // The size check could be relaxed to sz <= input_sz
        if sz == input_sz {
            Some(&*(xs.as_ptr() as *const U))
        } else {
            None
        }
    }
    

    【讨论】:

    • 使用宏可以确保安全吗?
    • 我宁愿在所有小数组大小上实现必要的标记特征,并使用它来消除不安全的。我想它可以通过宏来保证安全。
    猜你喜欢
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 2019-05-25
    • 2016-10-16
    相关资源
    最近更新 更多