我在websocket库中发现了一些复杂的代码,似乎在Receiver
特征中调用了一个抽象函数。
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;
}
看起来它应该不起作用,因为Rust不知道要调用哪个函数。它是如何工作的?
答案 0 :(得分:3)
关键是方法的签名:
fn from_dataframes<D>(frames: Vec<D>) -> WebSocketResult<Self>
当编译器统一类型时,它可以使用返回类型recv_message
( ie WebSocketResult<M>
)来推断from_dataframes
的结果必须是同一类型,这意味着有问题的Self
类型为M
,这意味着您真正的含义是:
<M as Message>::from_dataframes(dataframes)
如果实现类型和方法签名之间没有连接,那么它将无法工作,因为编译器没有任何基础可以作为其基础。