Общий способ владения значением (не указывайте `Rc` или `Box`)

Существует ли перечисление/признак для принадлежащих значений в целом, когда вы не хотите указывать, как именно значение принадлежит (совместно или нет), но вы просто хотите им владеть.< br> Мне нужно хранить ссылки на замыкания в структуре, а это значит, что они должны жить, пока существует структура. Я не могу копировать их, конечно, поэтому они должны быть ссылками. Но я не хочу вводить ограничения, поэтому пользователь структуры должен иметь возможность выбирать, как он хочет передать право собственности.
Это общая проблема, когда вы не можете скопировать значения или если они действительно большой.

Очень общий пример, я ищу это Owned<T>

struct Holder<T> {
    value: Owned<T>,
}

...

let rc = Rc::new(variable);
let holder = Holder::new(rc.clone());
let holder2 = Holder::new(Box::new(variable2));

Примером очень простой «реализации» этого типа может быть:

enum Owned<T> {
     Unique(Box<T>),
     Shared(Rc<T>),
}

Надеюсь, я смог объяснить, что я имею в виду.


person Kapichu    schedule 03.07.2015    source источник


Ответы (1)


Я думаю, вы можете быть немного сбиты с толку словом «владеет», которое понятно в Rust! Каждое значение кому-то принадлежит, но иногда значение ссылается на что-то, чем вы не владеете.

В вашем случае вам просто нужно принять T. Тогда Holder будет владеть T:

use std::rc::Rc;

struct Holder<T> {
    value: T,
}

impl<T> Holder<T> {
    fn new(v: T) -> Holder<T> {
        Holder { value: v }
    }
}

fn main() {
    let variable = "Hello world".to_owned();
    let variable2 = "Hello moon".to_owned();

    let rc = Rc::new(variable);
    let holder = Holder::new(rc.clone());
    let holder2 = Holder::new(Box::new(variable2));
}

Даже если вы передадите ссылку Holder, ему будет принадлежать ссылка. Однако он не будет владеть упомянутым предметом.

person Shepmaster    schedule 04.07.2015
comment
Подождите, как возможно передать Box<T> или Rc<T> функции, когда она ожидает T? Это разные типы, и у нас нет неявного преобразования в Rust! Однако я протестировал его, и он компилируется! is.gd/Pwo5hu - person Kapichu; 04.07.2015
comment
@Kapichu: Вас сбивает с толку использование T, так что давайте перепишем это impl <U> Holder<U> { value: U, }. Если U может быть любого типа, то это может быть T, Box<T>, Rc<T> или Vec<T>, не так ли? - person Matthieu M.; 04.07.2015
comment
Так что я могу с уверенностью предположить, что могу использовать Box<T> или Rc<T> точно так же, как T? - person Kapichu; 04.07.2015
comment
@Капичу, ага! Как написано, Holder не накладывает ограничений на принимаемый тип. - person Shepmaster; 04.07.2015
comment
Хм, но теперь держатель ничего не может сделать со значением, в моем случае значение является функцией, поэтому оно должно реализовать FnMut, чего нельзя сказать о Box или Rc. - person Kapichu; 04.07.2015
comment
Разве DerefMut<Target = FnMut> не будет моим решением? Когда мне нужно вызвать функцию, я просто разыменовываю ее. Box и Rc и другие должны их реализовать. - person Kapichu; 04.07.2015
comment
@Kapichu в целом звучит правильно. Однако Rc предназначен для неизменяемых данных, поэтому это не сработает. Однако похоже, что вы отклоняетесь от своего исходного вопроса (общее владение значением), поэтому вы можете задать другой, более конкретный вопрос, чтобы лучше понять его. - person Shepmaster; 04.07.2015