我想要了解Rust生命周期 . 虽然我似乎理解它们,但我似乎并不知道解决它的最佳方法 . 这是一个函数,我使用* ring *包生成SHA256 HMAC . 以下是复制问题的函数的简化版本:
fn sign<'b>(data: &[u8], key: &[u8]) -> &'b [u8] {
let hmac_key = hmac::SigningKey::new(&digest::SHA256, key);
let signature = hmac::sign(&hmac_key, data);
let data = signature.as_ref();
data
}
这不起作用,因为 signature
的寿命不够长 . 那讲得通; as_ref
具有对 signature
的引用,并且签名不会超过函数的结尾 .
as_ref
是* ring *中推荐的从 Digest
结构获取 &[u8]
的方法,如documentation所示 .
如何在不复制字节数组的全部内容的情况下纠正 signature
不能存活多久的问题?
1 回答
signature
绑定到一个资源,该资源实际上只存在于该函数的范围内 . 当然,将签名的数组(也包含在函数中)借给生活在函数之外的东西是错误的 . 因此,按照您的意图延长其使用寿命是不可能的 .考虑到这一点,有两种方法可以解决这个问题,按优先顺序排列:
我们可以通过使函数返回
Digest
将signature
的所有权传递给外部 . 注意这个doesn't mean that there will be deep copies of the content . 可以进行返回值优化,如果返回值大于指针,则会生成返回的对象 . 另一方面,这似乎更像是语言的保证而不是语言的保证 . 如果这是一个真正的问题,我会调查编译的程序集 .或者,可以重写(或使用扩展的API修改)库以接受对缓冲区的可变引用(可能需要支持调整大小,例如
&mut Vec<u8>
) . 当然,这意味着建议并实施对此库的可接受的更改,但前一种方法可能就足够了 .