#rust #serde
#Ржавчина #serde
Вопрос:
Я новичок в Rust, поэтому я уверен, что мне не удается найти здесь что-то элементарное, но…
У меня есть файл конфигурации yaml, который я хочу десериализовать в простую структуру. В более ранней версии я мог нормально выполнять это из строкового литерала, но теперь, когда я переработал его для чтения из файла, я получаю сообщение об ошибке implementation of '_::_serde::Deserialize' is not general enough
. Моя функция выглядит так:
fn read_config(file: amp;str) -> Result<Config, amp;'static str> {
match std::fs::read_to_string(file) {
Ok(yaml) => match serde_yaml::from_str(amp;yaml) {
Ok(c) => c,
Err(_) => Err("Failed to parse yaml config."),
},
Err(_) => Err("Could not open supplied config file"),
}
}
read_to_string
возвращает a Result<String>
, но подпись для serde_yaml::from_str
требует amp;str
, то есть заимствования. Когда я даю ему заимствование, как указано выше, я получаю ошибку «недостаточно общая». Когда я гуглю эту ошибку, я вижу много дискуссий о том, что десериализатор не может использовать заимствованные данные; сначала я должен владеть ими. Разве это не то, что в оригинале String
? Если from_str
нельзя использовать заимствование, почему оно принимает amp;str
в качестве аргумента? Чего мне здесь не хватает?
Ответ №1:
Проблема не в переданном вами строковом параметре.
Согласно документации, from_str
возвращает Result<T>
. В этом случае вам нужно будет вызвать функцию с ожидаемым типом для T
. Здесь это было бы serde_yaml::from_str::<Config>(amp;yaml)
.
Вам также необходимо исправить свой оператор возврата для c
. Это было бы Ok(c)
, не только c
.
Комментарии:
1. Да, я понял это так же, как вы опубликовали.
::<Config>
Является избыточным, если возврат исправлен, но это все. Спасибо!2. Я опубликовал свой ответ всего на секунду позже, кажется, вы уже нашли решение. Вы правы, вывод типа не произошел из-за оператора return, он действительно избыточен.
Ответ №2:
Конечно же, я упустил что-то фундаментальное. Проблема не имела ничего общего с заимствованиями или владением. Я пропустил перенос конечного результата в Ok()
, что испортило вывод типа для моего вызова from_str
. Исправленная функция:
fn read_config(file: amp;str) -> Result<Config, amp;'static str> {
match std::fs::read_to_string(file) {
Ok(yaml) => match serde_yaml::from_str(amp;yaml) {
Ok(c) => Ok(c),
Err(_) => Err("Failed to parse yaml config."),
},
Err(_) => Err("Could not open supplied config file"),
}
}