2017-02-01 9 views
2

У меня есть признак для чтения и записи потоков (например, TcpStream):Черта реализации с определенной структурой в качестве параметра

pub trait MyTraitPool<T: Read + Write> { 
    fn acquire(&self, &String) -> T; 
    fn free(&self, T); 
} 

Я хочу осуществить эту черту с TcpStream как T, так что я хотел бы написать

struct MyPool; 

impl<T> MyTraitPool<T> for MyPool 
    where T: Read + Write { 

    fn acquire(&self, addr: &String) -> T { 
     TcpStream::connect(addr.as_str()).unwrap() 
    } 

    fn free(&self, con: T) { 
     con.shutdown(Shutdown::Both); 
    } 
} 

Я получаю ошибку «ожидаемый тип параметра, найденный struct std::net::TcpStream» в методе acquire. Что касается метода free, я знаю, что shutdown является TcpStream -специфичным, но я хотел бы иметь конкретную реализацию для TcpStream s в этой точке и, следовательно, иметь возможность называть TcpStream -специфическими методами. Итак, как я могу это сделать?

В качестве побочного примечания: реализация является лишь примером того, что я хотел бы сделать, а не как работает код позже!

+0

У меня возникают разные проблемы: «ожидаемый тип параметра, найденный enum' std :: result :: Result' »(вам не хватает' unwrap' в коде выше?) И «no method с именем' shutdown' найдено для типа 'T' в текущей области действия (при условии, что вы используете только' std :: net :: {TcpStream, Shutdown} и 'std :: io :: {Read, Write}'). – ljedrz

+0

@ljedrz реализация выше - это всего лишь образец, поэтому я не проверял типы возвращаемых данных или управление ошибками и т. Д. (Я хотел сохранить цель простой и удобочитаемой). Вторая проблема фактически упоминается в тексте выше;) –

+1

Ах да, я не читал достаточно внимательно :). Тем не менее, всегда рекомендуется указывать код, который воспроизводит точный вопрос, который у вас возникает при компиляции ([MCVE] (http://stackoverflow.com/help/mcve)). Это значительно облегчает поиск подходящего решения к вашему конкретному случаю. – ljedrz

ответ

1

Вместо того, чтобы сделать MyTraitPool признак родовым, вы бы сделать ваш MyPool родовым, и вы бы создать промежуточный MyStream черт, чтобы предложить вам все методы, необходимые:

trait MyStream: Read + Write { 
    fn connect(&str) -> Self; 
    fn shutdown(self); 
} 
impl MyStream for TcpStream { 
    fn connect(addr: &str) -> Self { TcpStream::connect(addr) } 
    fn shutdown(self) { TcpStream::shutdown(self, Shutdown::Both); } 
} 
impl<T: MyStream> MyTraitPool for MyPool<T> { 
    fn acquire(&self, addr: &str) -> T { 
     MyStream::connect(addr) 
    } 
    fn free(&self, con: T) { 
     con.shutdown() 
    } 
} 

Streams, которые на самом деле не нужен shutdown, просто оставит реализацию пустой.

+0

Это похоже на хорошую идею, и мне удалось скомпилировать ее, спасибо вам большое! Думаю, сегодня я узнал что-то новое :) –