Как я могу проверить функции других признаков объекта - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть структура Template, реализующая функцию encoder, которая возвращает ссылку на Box ed Encoder.

У меня также есть структура FixedEncoder, которая реализует Encoder

Я могу создать Template и получить Encoder, но как мне проверить функции FixedEncoder? Я только хочу получить FixedEncoder для целей тестирования, поэтому «небезопасные» решения хороши (хотя безопасные предпочтительнее)

В моем следующем примере я получаю ошибку

error[E0599]: no method named `length` found for type `&std::boxed::Box<(dyn Encoder + 'static)>` in the current scope

Пример ( детская площадка ):

pub struct Template {
    encoder: Box<Encoder>
}

impl Template {
    fn new(encoder: Box<Encoder>) -> Template {
        Template { encoder }
    }

    fn encoder(&self) -> &Box<Encoder> {
        &self.encoder
    }
}

pub trait Encoder {
    fn isEncoder(&self) -> bool {
        true
    }
}

pub struct FixedEncoder {
    length: usize
}

impl FixedEncoder {
    pub fn new(length: usize) -> FixedEncoder {
        FixedEncoder { length }
    }

    pub fn length(&self) -> usize {
        self.length
    }
}

impl Encoder for FixedEncoder {}

fn main() {
    let fixed_encoder = FixedEncoder::new(1);
    let template = Template::new(Box::new(fixed_encoder));
    assert_eq!(template.encoder().isEncoder(), true); // works
    assert_eq!(&template.encoder().length(), 1); // error[E0599]: no method named `length` found for type `&std::boxed::Box<(dyn Encoder + 'static)>` in the current scope
}

1 Ответ

0 голосов
/ 15 ноября 2018

Мне удалось сделать это с помощью Any.

  1. Добавить объявление as_any к Encoder
  2. Добавить функцию as_any к FixedEncoder
  3. Использование .as_any().downcast_ref().unwrap() на полученном Encoder

детская площадка

use std::any::Any;

pub struct Template {
    encoder: Box<Encoder>
}

impl Template {
    fn new(encoder: Box<Encoder>) -> Template{
        Template {
            encoder
        }
    }
    fn encoder(&self) -> &Box<Encoder> {
        &self.encoder
    }
}

pub trait Encoder {
    fn isEncoder(&self) -> bool {
        true
    }
    fn as_any(&self) -> &dyn Any;
}

pub struct FixedEncoder {
    length: usize
}
impl FixedEncoder {
    pub fn new(length: usize) -> FixedEncoder {
        FixedEncoder { length }
    }
    pub fn length(&self) -> usize {
        self.length
    }
}



impl Encoder for FixedEncoder {
    fn as_any(&self) -> &dyn Any {
        self
    }
}

fn main() {
    let fixed_encoder = FixedEncoder::new(1);
    let template = Template::new(Box::new(fixed_encoder));
    assert_eq!(template.encoder().isEncoder(), true); // works

    let fixed_encoder_from_template : &FixedEncoder = &template.encoder().as_any().downcast_ref().unwrap();
    assert_eq!(&fixed_encoder_from_template.length, &(1 as usize));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...