Почему Serde не поддерживает типы R c и Ar c по умолчанию? - PullRequest
3 голосов
/ 09 марта 2020

Пожалуйста, объясните функцию Serde rc

Включите impls для Rc<T> и Arc<T>. Сериализация и десериализация этих типов не сохраняет идентичность и может привести к нескольким копиям одних и тех же данных. Перед включением этой функции убедитесь, что это именно то, что вам нужно.

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

Десериализация структуры данных, содержащей указатели с подсчетом ссылок, не будет пытаться дедуплицировать ссылки на одни и те же данные. Каждый десериализованный указатель будет иметь сильный счет 1.

Почему существует этот признак функции и почему он не работает по умолчанию? Что это означает под

Сериализация и десериализация этих типов не сохраняет идентичность и может привести к нескольким копиям одних и тех же данных

Я знаю, что это связано с выпуск Серде 194 . Последнее сообщение о проблеме говорит

Если вы хотите, чтобы случайно не получить производный impl, содержащий r c, откройте проблему .

Существует ли флаг функции для обнаружения неожиданного использования Rc struct?

1 Ответ

3 голосов
/ 09 марта 2020

Как указано в Выпуск Serde 194 , недостатками реализации десериализации до Rc или Arc являются:

  • Потенциально повышенное использование памяти
  • Сравнение равенства, которое основано на сравнении разрывов адресов
  • Изменчивость внутренней части не отражается в копиях

Это отражено в документации о флаге функции :

Сериализация не будет пытаться дедуплицировать эти повторяющиеся данные.

Десериализация структуры данных, содержащей указатели с подсчетом ссылок, не будет пытаться дедуплицировать ссылки на те же данные.

Обычная точка для Rc или Arc - доля данных. Такое совместное использование не происходит при десериализации структуры, содержащей Rc или Arc. В этом примере 5 совершенно разных Rc<str> создаются без отношения друг к другу, даже если все они имеют одинаковое содержимое:

use std::{rc::Rc, ptr};

fn main() {
    let json = r#"[
        "alpha",
        "alpha",
        "alpha",
        "alpha",
        "alpha"
    ]"#;

    let strings = serde_json::from_str::<Vec<Rc<str>>>(json).unwrap();

    dbg!(ptr::eq(strings[0].as_ref(), strings[1].as_ref()));
}
[src/main.rs:14] ptr::eq(strings[0].as_ref(), strings[1].as_ref()) = false

Это особенно плохо, если у вас есть Rc<RefCell<_>> или другой тип с изменчивостью внутренней части, поскольку можно ожидать, что изменение одного из элементов изменяет всех элементов.

См. Также:

...