Как я могу добавить методы расширения к признаку со связанными типами, лежащими в другом ящике? - PullRequest
3 голосов
/ 29 сентября 2019

Я пытаюсь добавить метод расширения к черте в другом ящике. Для этой черты указан связанный тип.

pub trait Test<W> {
    type Error;

    fn do_sth(&mut self) -> Result<W, Self::Error>;
}

Почему невозможно добавить метод, использующий связанный тип Error?

impl dyn Test<u8> {
    fn use_do_sth(&mut self) -> Result<u8: Self::Error> {
        self.do_sth()
    }
}

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

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

Когда вам нужно добавить метод к внешнему типу, единственный вариант - использовать признаки расширения . Это означает, что вы определяете свою собственную черту с любыми необходимыми вам методами и внедряете ее для нужных вам типов.

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

use std::fmt::Debug;

// This is an extension trait.
// You can force all its implementors to implement also some external trait,
// so that two trait bounds essentially collapse into one.
trait HelperTrait: Debug {
    fn helper_method(&mut self);
}

// And this is the "blanket" implementation,
// covering all the types necessary.
impl<T> HelperTrait for T where T: Debug {
    fn helper_method(&mut self) {
        println!("{:?}", self);
    }
}

Playground

Та же идея может быть применена к любой внешней черте, так какВы хотите.

1 голос
/ 29 сентября 2019

Хотите следующее?

impl<E> dyn Test<u8, Error = E> {
    fn use_do_sth(&mut self) -> Result<u8, E> {
        self.do_sth()
    }
}

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

...