2017-03-15 21 views
1

形質で抽象関数を呼び出すと思われるwebsocketライブラリに複雑なコードがいくつか見つかりました。抽象関数を呼び出すことはできますか?

fn recv_message<'m, D, M, I>(&mut self) -> WebSocketResult<M> 
    where M: Message<'m, D, DataFrameIterator = I>, 
      I: Iterator<Item = D>, 
      D: DataFrame 
{ 
    let dataframes = try!(self.recv_message_dataframes()); 
    Message::from_dataframes(dataframes) // Isn't this an abstract function? 
} 

ws::Message形質のコード:錆を呼び出すように機能しているか分からないでしょうので、それが動作してはならないように見えます

pub trait Message<'a, F>: Sized 
    where F: DataFrame 
{ 
    type DataFrameIterator: Iterator<Item = F>; 
    fn from_dataframes<D>(frames: Vec<D>) -> WebSocketResult<Self> where D: DataFrame; 
    fn dataframes(&'a self) -> Self::DataFrameIterator; 
} 

。どのように機能するのですか?

答えて

3

キーは、メソッドのシグネチャです:

fn from_dataframes<D>(frames: Vec<D>) -> WebSocketResult<Self> 

コンパイラが型を統一するために行くとき、それがあること​​の結果を推測する(WebSocketResult<M>すなわちrecv_messageの戻り値の型を使用することができますあなたが本当にが意味したものだったことを意味し、当該SelfタイプがMであることを意味し、同じタイプ、である必要があります。

<M as Message>::from_dataframes(dataframes) 

実装の型とメソッドのシグネチャの間に接続がなかった場合、コンパイラはその推論を基にするものがないため、動作しません。

+0

錆のタイプのシステムはとてもスマートです!回答ありがとうございます ! –

+0

@AtsukiTakahashi:Pedantically、これは型システムではなくコンパイラがここでスマートです。そしてはい、rustcはすべての種類のスマートです! –

関連する問題