Существует ли общий указатель с одним сильным владельцем и несколькими слабыми ссылками? - PullRequest
0 голосов
/ 08 июня 2018

Я ищу умный указатель, похожий на Arc / Rc, за исключением того, что он не допускает совместное владение.

Я хочу иметь столько ссылок rc::Weak, сколько мне нужно, но ятолько хочу один сильная ссылка, иначе владелец.И я хочу применить это к системе типов.

Arc / Rc можно клонировать, и им можно владеть в нескольких местах.

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

Я ищу структуру данных, обеспечивающую такой интерфейс:

impl MySmartPointer<T> {
    fn new(object: T) -> Self;
    fn weak_ref(&self) -> WeakRef<T>;
    fn get_mut(&mut self) -> &mut T;
}

impl WeakRef<T> {
    /// If the strong pointer `MySmartPointer` has been dropped,
    /// return `None`. Else return Some(&T);
    fn get(&self) -> Option<&T>;
}

1 Ответ

0 голосов
/ 08 июня 2018

Предположим, он существует с типами Strong<T> и Weak<T>.Как вы используете Weak<T>?Вам нужен какой-то ошибочный шаг «апгрейда», так что же до Weak<T> нужно обновить?Это не может быть простой ссылкой (как вы заявили), потому что Strong<T> нужно , чтобы знать, существуют ли какие-либо "модернизированные" Weak<T>.Если этого не произошло, он мог бы освободить свое хранилище, пока к значению все еще обращаются.

Так что Weak<T> должен обновиться до некоторого вида SemiWeak<T>, который поддерживает базовое распределение живым ... что точноЧто такое общее владение .

Что если вы каким-то образом гарантируете, что Strong<T> не может быть освобожден до того, как все Weak<T> уйдут?Поздравляем, вы только что заново изобрели T и &T: вы могли буквально просто использовать их вместо этого.

Хорошо, так что что, если вы сделали это так, чтобы Weak<T>обновляется до SemiWeak<'a, T>, привязанного ко времени жизни Weak<T>, так что не может пережить его и может быть только временным?Все, что вы действительно делаете в этом случае, это скрывает тот факт, что у вас есть общее право собственности.Под капотом SemiWeak все еще нужно будет гарантировать, что базовый Strong не может исчезнуть.Вы можете создать такой тип из Rc<T> за десять минут.Это фактически даст вам тип, точно такой же, как Rc<T>, с той же производительностью и стоимостью памяти, но менее полезный.

Кроме того, этот метод get_mut не может существовать.Нет способа предотвратить существование SemiWeak<T> s.Если вы не используете заимствования, но, опять же, это просто использование T и &T.

Так что нет, я не думаю, что это существует, и при этом я не верю, что может вформа, которую вы описали.


В качестве окончательного варианта, просто наличие Weak<T> на всех является формой совместного владения, потому что эти Weak<T> s нужно указать на что-то .В случае Rc<T> слабый счетчик сохраняется прямо рядом с сильным счетчиком, поэтому, пока значение может быть уничтожено, само распределение остается неизменным.Вы могли бы разделить два, но теперь вы платите за два распределения и двойное косвенное обращение (вероятно, приводящее к большему количеству промахов кэша).

...