且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Rust中将内部可变性与泛型一起使用?

更新时间:2023-01-17 07:51:12

我还是不想复制它.我宁愿有一个[code.self.digest ]的实例.

问题在于 self.digest.chain() 消耗(拥有) self.digest 的所有权,这是一个基本部分不能更改的 Digest :: chain()合约的期限.内部可变性将无济于事,因为这不是可变性问题,而是对象生存期问题-移动或放置对象后,您将无法使用它.

The problem is that self.digest.chain() consumes (takes ownership of) self.digest, and that's a fundamental part of the contract of Digest::chain() which you cannot change. Interior mutability won't help because it's not a mutability issue, it's an object lifetime issue - you cannot use an object after it is moved or dropped.

您的使 digest 成为创建摘要的函数的想法应该起作用.它将需要两种通用类型,一种是摘要类型,特征绑定为 Digest ,另一种类型是工厂,特征绑定为 Fn()->.D :

Your idea to make digest a function that creates digests should work, though. It will require two generic types, one for the digest type, with a trait bound of Digest, and the other for the factory, with a trait bound of Fn() -> D:

struct Crypto<F> {
    digest_factory: F,
}

impl<D, F> Crypto<F>
where
    D: Digest,
    F: Fn() -> D,
{
    pub fn hash(&self, data: &[u8]) -> Vec<u8> {
        (self.digest_factory)()
            .chain(&data)
            .finalize()  // use finalize as the object is not reused
            .to_vec()
    }
}

如何避免复制 to_vec()而只返回 finalize_reset()返回的数组?

您可以让 hash()返回与 finalize() digest :: Output< D> :

pub fn hash(&self, data: &[u8]) -> digest::Output<D> {
    (self.digest_factory)()
        .chain(&data)
        .finalize()
}