Можно ли использовать std:: rc:: Rc с типом признака?


Код выглядит так:

// Simplified
pub trait Field: Send + Sync + Clone {
    fn name(&self);
}

#[deriving(Clone)]
pub enum Select {
    SelectOnly(Vec<Rc<Field>>),
    SelectAll
}

Ошибка такова:

the trait `core::kinds::Sized` is not implemented for the type `Field+'static`

Есть ли другой способ получить вектор с отсчетными неизменяемыми объектами типа признака?

Я полагаю, что могу переписать код следующим образом:

#[deriving(Clone)]
pub enum Select {
    SelectOnly(Vec<Rc<Box<Field>>>),
    SelectAll
}

Это правильный путь?

3 5

3 ответа:

Я считаю, что это должно быть возможно с DST, но ржавчины пока нет. Основной мотивацией для DST было именно желание использовать объекты признаков с любым типом интеллектуального указателя. Насколько я знаю, это должно быть возможно к выпуску 1.0.

В качестве временного обходного пути, действительно, можно использовать Rc<Box<T>>, хотя этот вид двойного косвенного обращения неудачен.

Можно создать объект признака с Rc по состоянию на Rust 1.1. Это компилирует:

use std::rc::Rc;

trait Field: Send + Sync {
    fn name(&self);
}

enum Select {
    Only(Vec<Rc<Field>>),
    All,
}

// ---

struct Example;
impl Field for Example {
    fn name(&self) {}
}

fn main() {
    let fields: Vec<Rc<Field>> = vec![Rc::new(Example)];
    Select::Only(fields);
}
Обратите внимание, что ваш исходный пример использовал Clone, но вы не можете превратить такой признак в объект признака, потому что это не объект safe. Я удалил его, чтобы ответить на вопрос.

Я также устранил избыточность имен вариантов перечисления.

Это будет возможно после #18248 и еще #16918.