Почему возникает ошибка (завершающие символы) при попытке десериализации файла JSON в хэш-карту?

По сути, я пытаюсь десериализовать файл JSON в хэш-карту ‹String, String›, используя ящик serde, но. Файл JSON:

"
    [
        {
            "orchard_name": "Happy Apple",
            "tons": "5"
        },
        {
            "orchard_name": "Munch for Lunch",
            "tons": "2"
        }
    ]
    "

Это моя структура:

#[derive(Serialize, Deserialize, Debug)]
struct OrangeFarm
{
    map : HashMap<String,String>
}

и здесь я пытаюсь выполнить десериализацию:

let res = serde_json::from_str(_json);
if res.is_ok() {println!("Deserealization worked."); }
else { println!("it went wrong"); }
let mut deserializedFarm : OrangeFarm = res.unwrap();

По какой-то причине это сработает, если я удалю второй {}, но этого не произойдет, если я позволю второму {}, поскольку я получаю этот поток ошибок 'main', который запаниковал ', называемый Result::unwrap() на значении Err: Ошибка (конечные символы. Вы хоть представляете, почему это происходит? Спасибо!


person thebalkandude    schedule 24.03.2021    source источник
comment
Действительно ли ваш файл JSON содержит пару кавычек, окружающих все?   -  person mcarton    schedule 24.03.2021
comment
Действительно ли файл json содержит самую первую и самую последнюю цитату? Кроме того, ваш JSON кажется массивом объектов, но вы пытаетесь десериализовать его в структуру, содержащую HashMap   -  person derpirscher    schedule 24.03.2021
comment
У них есть самая первая и последняя цитата.   -  person thebalkandude    schedule 24.03.2021


Ответы (1)


По какой-то причине это работает, если я удалю второй {}, но не работает, если я позволю второму {}

Я понятия не имею, что это означает, но, насколько я понимаю, это никогда не работает: вы пытаетесь десериализовать массив структур, но десериализуете структуру. Таким образом, десериализация логически не выполняется. Код всегда вызывает панику, хотя в первом случае он также выводит сообщение о том, что все пошло не так.

Кроме того, определение вашей структуры не соответствует JSON, поэтому даже если вы попытаетесь десериализовать Vec<OrangeFarm>, вызов не удастся: serde ожидает найти атрибут map, которого нет в JSON. Поэтому вам нужно либо исправить свою структуру, либо настроить схему сериализации / десериализации.

Десериализация в Vec<HashMap<String, String>> будет работать, но я понятия не имею, является ли это вашим намерением.

Помимо этого:

  • Предоставьте минимальные полные запускаемые варианты воспроизведения, используя play.rust -lang.org, когда это возможно (это здесь), и использовать обычные блоки кода, чтобы показать случай в комментарии, эти фрагменты html явно не могут работать для ржавчины (особенно когда код даже не завершен), поэтому они просто займите место и нарушите окраску синтаксиса
  • Какой там маленький код ... странный. Обычно не нужно проверять _5 _ / _ 6_, а затем сразу же разворачивать, вместо этого вы должны использовать match или if let, чтобы аккуратно выполнить и то, и другое одновременно и избежать риска рассинхронизации, недопонимания и т. Д. Бывают ситуации, когда unwrap.
  • Вызов переменной, которую вы активно используете _json, является ненормальным, префикс _ предназначен для переменных, которые вы хотите захватить, но не хотите использовать (он подавляет unused_variables линт без немедленного сброса значения, что было бы эффектом одиночного _ ).
person Masklinn    schedule 24.03.2021
comment
Ладно извини. Я новичок в Stackoverflow. Итак, какой тип данных мне лучше всего выбрать для десериализации моего файла JSON? Я думал, что могу десериализовать JSON напрямую в HashMap, но это не сработало. - person thebalkandude; 24.03.2021
comment
Мне нужно как-то подсчитать сумму в тоннах. Так что я думаю, что ваш метод с Vec не сработает. Я думал о создании структуры с двумя Vec ‹String›, но это не сработает, потому что это последовательность, а JSON - это карта. - person thebalkandude; 24.03.2021
comment
JSON - это массив карт, поэтому десериализация в вектор карт является наиболее простой задачей и отлично работает. Если вам нужно суммировать значения, вам все равно нужно явно преобразовать их строки fsrom в целые числа. Или вы можете выполнить десериализацию до Vec<OrchardInfo> где struct OrchardInfo { orchard_name: String, tons: String }, чтобы избежать накладных расходов на хэш-карты. Используя serde_with и правильную аннотацию, можно даже иметь tons: usize или tons:u32, чтобы избежать явного шага десериализации. - person Masklinn; 24.03.2021
comment
Я думал о десериализации в Vec ‹Obj›, где Obj - это структура с двумя строками. Я имею в виду то, что я могу понять из файла JSON. Это массив объектов. Так почему это не должно работать? @Masklinn Мы писали одновременно. Так я и думал об этом. Спасибо, сэр! Я попробую - person thebalkandude; 24.03.2021