保留u8数组返回值中变量的生命周期

时间:2016-09-27 21:46:59

标签: rust lifetime

我正试图抓住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 *中的推荐方式,可以从&[u8]结构中获取Digest,如documentation中所示。

如果不复制字节数组的全部内容,如何更正signature不能存活多久的问题?

1 个答案:

答案 0 :(得分:2)

signature绑定到一个资源,它实际上只存在于该函数的范围内。当然,将签名的数组(也包含在函数中)借给生活在函数之外的东西是错误的。因此,按照您的意图延长其使用寿命是不可能的。

考虑到这一点,有两种方法可以解决这个问题,按优先顺序排列:

  • 我们可以通过让函数返回signature来将Digest的所有权传递给外部。请注意这个doesn't mean that there will be deep copies of the content。可以进行返回值优化,如果返回值大于指针,则会生成返回的对象。另一方面,这似乎更像是implementation detail而不是语言的保证。如果这是一个真正的问题,我会调查已编译的程序集。
  • 或者,可以重写(或使用扩展的API修改)库以接受对缓冲区的可变引用(可能需要支持调整大小,例如&mut Vec<u8>)。当然,这意味着建议并实施对此库的可接受的更改,但前一种方法可能就足够了。