【问题标题】:Retain lifetime of variable in returned value for array of u8在 u8 数组的返回值中保留变量的生命周期
【发布时间】:2017-02-05 16:28:22
【问题描述】:

我正在尝试掌握 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 结构中获取 &amp;[u8] 的方法,如 documentation 所示。

如果不复制字节数组的全部内容,我该如何纠正signature 的寿命不够长的问题?

【问题讨论】:

  • 为什么要返回&amp;[u8]?一个名为sign 的函数返回Digest 似乎是完全自然的。

标签: rust lifetime


【解决方案1】:

signature 绑定到一个资源,因为它只存在于该函数的范围内。当然,将同样存在于函数中的签名数组借给存在于函数之外的东西是错误的。因此,按照您的意愿延长其生命周期是不可能的。

考虑到这一点,有两种方法可以解决这个问题,按偏好排序:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 2021-05-31
    • 2023-03-24
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多