2016-09-27 31 views
0

我試圖獲得Rust壽命的掛起。雖然我似乎理解他們,但我似乎並不知道解決問題的最佳方法。這裏是一個函數,我使用* ring *包生成SHA256 HMAC。下面是重現該問題的功能的簡化版本:保留U8數組返回值中的變量的生命期

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長度不夠長的問題?

+5

你爲什麼要返回'&[u8]'?對於稱爲「sign」的函數來說,返回一個「Digest」似乎是完全自然的。 – delnan

回答

2

signature綁定到一個資源,因爲它只會生活在該函數的範圍內。當然,將簽名的陣列借給生活在功能之外的東西也是錯誤的。因此,按照您的意願擴大其使用壽命是不可能的。

考慮到這一點,有兩種方法去解決這個問題,按優先順序排列:

  • 我們可以只通過的signature的所有權外,通過使函數返回Digest。請注意,這doesn't mean that there will be deep copies of the content。可以進行返回值優化,如果返回值大於指針,將產生返回的對象。另一方面,這似乎更多的是implementation detail而不是語言的保證。如果這是真正的問題,我會研究編譯後的程序集。
  • 或者,可以重寫庫(或使用擴展API修改)以接受對緩衝區(可能需要支持調整大小的可變引用,如&mut Vec<u8>)的可變引用。當然,這意味着提出並實施對這個圖書館的可接受的改變,但是對於你的問題的前一種方法可能就足夠了。