Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

returns a value referencing data owned by the current function [duplicate]

Tags:

rust

This code is throwing an error about returning a reference from the function:

fn sha512_256_digest(str: &[u8]) -> &[u8] {
    let x = digest::digest(&digest::SHA512_256, str);
    x.as_ref()
}

What would be the correct way to return the as_ref() value of x here?

like image 960
themonkey Avatar asked Nov 14 '19 16:11

themonkey


2 Answers

Short answer: You can't. That's because digest() returns an owned value and as_ref() (by definition) borrows from it. When the function returns, the memory owned by the return value of digest() is destroyed and the referenced returned by as_ref() becomes invalid.

I guess your goal is to hide the implementation detail that digest() returns a GenericArray, while you only need a &[u8]. You can get something similar by hiding the concrete type:

fn sha512_256_digest(str: &[u8]) -> impl AsRef<[u8]> {
    digest::digest(&digest::SHA512_256, str)
}

... should work. The function signature says that the return value will be some anonymous type which the caller can only ever know about that it can be referenced as if it was a &[u8]. The caller can do

// `d` is of some anonymous type
let d = sha512_256_digest(...);

// `db` is a &[u8]
let db = d.as_ref();

However, I'd recommend not to hide types in such a way.

like image 138
user2722968 Avatar answered Oct 14 '22 16:10

user2722968


Since the value you're returning is created in (and thus owned by) the function, a reference to it cannot be returned as it won't exist once the function finishes.

You must either change the function to return an owned value or make its argument a mutable reference &mut [u8] and remove the return - so your options for function signatures would probably be one of the following:

fn sha512_256_digest(str: &mut [u8])

or

fn sha512_256_digest(str: &[u8]) -> Vec<u8>

A complete example with the former would be:

let mut x = <insert your byte array here>;
sha512_256_digest(&mut x);
<use x here>

A complete example with the latter would be:

let x = <insert your byte array here>;
let y = sha512_256_digest(&x);
<use y here>
like image 4
notquiteamonad Avatar answered Oct 14 '22 17:10

notquiteamonad