2016-09-27 6 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_refdocumentationに見られるように、そのDigest構造から&[u8]を取得する* *リングで推奨される方法です。

signatureがバイト配列の内容全体をコピーせずに十分に長く存続しない問題を解決するにはどうすればよいですか?

+5

なぜあなたは '&[u8]'を返そうとしますか? 'sign'という関数が' Digest'を返すのは完全に自然なことです。 – delnan

答えて

2

signatureは、その機能のスコープ内にのみ存在するリソースにバインドされます。当然ながら、関数の中に生きているシグネチャの配列を、関数の外にある何かに貸すことは、間違っているだけです。したがって、あなたが意図したように、その寿命を延ばすことは疑問ではありません。私達はちょうど関数はDigestを返すことで、外部へsignatureの所有権を渡すことができ

  • :念頭に置いて

    、好みによって注文この一周するには、2つの方法があります。これはdoesn't mean that there will be deep copies of the contentです。戻り値の最適化が行われ、ポインタより大きい場合は、返されたオブジェクトがインプレースで生成されます。一方、これは言語の保証ではなく、implementation detailのようです。これが真の関心事なら、私はコンパイルされたアセンブリを調べます。
  • また、バッファへの変更可能な参照(&mut Vec<u8>などのサイズ変更をサポートする必要がある可能性があります)を受け入れるために、ライブラリを書き直す(または拡張APIで変更する)ことができます。もちろん、これは、このライブラリに許容可能な変更を提案して実装することを意味しますが、問題への前のアプローチで十分です。
関連する問題