我希望在Rust中设计一个结构体,可以使用实现了
这个无法编译,因为在方法签名中
无论如何,我宁愿不复制它。我宁愿只有一个实例。我尝试过以下一些方法:
额外奖励 - 如何避免
Digest
trait的对象进行构造,并通过一个方法抽象哈希行为。这里是一个简单的例子,但它不能编译:use digest::Digest;
struct Crypto<D: Digest> {
digest: D,
}
impl<D> Crypto<D>
where
D: Digest,
{
pub fn hash(&self, data: &[u8]) -> Vec<u8> {
self.digest.chain(&data).finalize_reset().to_vec()
}
}
这个无法编译,因为在方法签名中
self
是不可变借用的,所以无法对 self.digest
进行不可变借用。因此尝试复制它,但由于泛型 D
没有定义遵循 Copy
特性,所以失败了。无论如何,我宁愿不复制它。我宁愿只有一个实例。我尝试过以下一些方法:
将方法签名更改为使用
mut self
。但这会将对象的所有权移动到方法中,之后不能再次使用。在
digest
字段中包装RefMut
或Cell
,以采用内部可变性,但我无法找出正确的方法来借用可变的digest
而不尝试复制该值。此外,如果可能的话,最好保持编译时的借用检查。将
D
的类型更改为返回Digest
实例的函数,并在hash()
方法中使用它来实例化新的摘要。但是,即使将其定义为D: Box<dyn Digest>
,编译器也会抱怨必须指定与特质digest::Digest相关联的OutputSize值
。因此,这似乎很具有挑战性,因为我想支持产生不同大小哈希的不同哈希算法。
额外奖励 - 如何避免
to_vec()
复制,并仅返回{{link1:finalize_reset()
返回的数组}}?
chain
。但是self.digest.update(&data); self.digest.finalize_reset().to_vec()
仍然想要将digest
借为不可变,但是无法实现。 - theorychain
函数之后,您可以更新hash
的方法签名,将&self
替换为&mut self
,这似乎符合您的所有要求,对吗? - pretzelhammerchain
想要移动digest
,所以删除它并且将签名更改为mut&self
确实可以解决它,只要我还将Crypto对象创建为可变的。不过最好保持内部化。 - theoryCrypto
实例都保持不可变是一个强制要求吗,还是...你希望人们甚至在一个不可变的Crypto
上也能调用hash
函数? - pretzelhammerupdate
需要结构本身来维护状态。 - theory