#rust
Вопрос:
match base64::decode(text) {
Ok(v) => str::from_utf8(amp;v).ok(),
_ => None
}
При использовании этой программы возникает следующая ошибка.
Я хотел бы, чтобы кто-нибудь объяснил, что это значит и что я должен делать.
cannot return value referencing local variable `v`
returns a value referencing data owned by the current function
`v` is borrowed here
Ответ №1:
Согласно base64::decode
документации, его подпись выглядит следующим образом:
pub fn decode<T: AsRef<[u8]>>(input: T) -> Result<Vec<u8>, DecodeError>
Ваш ввод принимается в качестве справки amp;[u8]
. Выход функции является собственным типом Result<Vec<u8>, DecodeError>
. Пока все хорошо.
Вы перемещаете результат base64::decode(text)
функции в match
выражение. В Ok
ветке вы перемещаете переменную Vec<u8>
into v
. Поймите, что теперь владельцем расшифрованного Vec<u8>
является v
. Внутри этой ветви вы заимствуете вектор с помощью amp;v
. Однако str::from_utf8
функция имеет подпись:
pub fn from_utf8(v: amp;[u8]) -> Result<amp;str, Utf8Error>
Это означает, что возвращаемое значение ему не принадлежит, оно все равно заимствует входное значение. Делая
Ok(v) => str::from_utf8(amp;v).ok()
вы пытаетесь вернуть эту заимствованную стоимость, однако помните, что владелец Vec<u8>
есть v
. После match
завершения выражения владелец v
уничтожается, данные Vec<u8>
уничтожаются.
Полученная вами ошибка уведомляет вас о том, что match
вы пытаетесь вернуть заимствованные данные, которые больше не будут действительны после match
завершения.
Самый простой способ исправить это-использовать String
тип вместо amp;str
типа, подобного этому:
let decoded = match base64::decode("aGVsbG8gd29ybGQ=") {
Ok(v) => String::from_utf8(v).ok(),
_ => None
};
println!("{:?}", decoded);
// Some("hello world")
Надеюсь, вы не будете тратить зря память, потому что в документации String::from_utf8
сказано, что
Этот метод позаботится о том, чтобы не копировать вектор, ради эффективности.