我一直在努力使一个库(
简而言之,我还剩下一个问题,已经尝试了数天仍未解决。可以用以下代码概括:
在上面的示例中,
我将整个 Rust Playground上的代码放了进去。
我希望我能更好地描述我的问题,以便更好地搜索它,因此一旦我知道发生了什么,我会更改我的标题。
rust-websocket
)使用更多的借用和较少的拥有数据。这涉及将一个Cow
添加到一个结构体中,这又涉及向该结构体添加生命周期,从而使得整个库需要生命周期。简而言之,我还剩下一个问题,已经尝试了数天仍未解决。可以用以下代码概括:
{ // This works great!
let mut sender = Wire;
let message = Text("Hello World!".to_string());
sender.send_message(&message);
}
{ // This DOES NOT COMPILE!
let mut client = Client {
sender: Wire,
packet: PhantomData,
};
let message = Text("Hello World!".to_string());
client.send(&message);
}
在上面的示例中,
client.send
是对 sender.send_message
的包装器,两者具有相同的定义。虽然在 client.send
的情况下,被发送的消息必须比客户端的生命周期更长。在 sender.send_message
的情况下,消息只需要在函数调用的生命周期内存在。use std::borrow::Cow;
use std::iter::{Take, Repeat, repeat};
use std::marker::PhantomData;
trait Sender<P> {
fn send_packet(&mut self, packet: &P) -> Result<(), ()>;
fn send_message<'m, M>(&mut self, message: &'m M) -> Result<(), ()>
where M: Message<'m, P>,
P: 'm
{
for ref packet in message.iter() {
try!( self.send_packet(packet) );
}
Ok(())
}
}
trait Message<'p, P>
where P: 'p
{
type PacketIterator: Iterator<Item = P>;
fn iter(&'p self) -> Self::PacketIterator;
}
#[derive(Clone, Debug)]
struct Packet<'d> {
data: Cow<'d, [u8]>,
}
struct Text(String);
impl<'p> Message<'p, Packet<'p>> for Text {
type PacketIterator = Take<Repeat<Packet<'p>>>;
fn iter(&'p self) -> Take<Repeat<Packet<'p>>> {
repeat(Packet {
data: Cow::Borrowed(self.0.as_bytes()),
}).take(1)
}
}
struct Wire;
impl<'s> Sender<Packet<'s>> for Wire {
fn send_packet<'p>(&mut self, packet: &Packet<'p>) -> Result<(), ()> {
println!("Sent {:?}", packet);
Ok(())
}
}
struct Client<P, S> {
sender: S,
packet: PhantomData<P>
}
impl<P, S> Client<P, S>
where S: Sender<P>
{
fn send<'m, M>(&mut self, message: &'m M) -> Result<(), ()>
where M: Message<'m, P>,
P: 'm
{
self.sender.send_message(message)
}
}
fn main() {
{ // This works great!
let mut sender = Wire;
let message = Text("Hello World!".to_string());
sender.send_message(&message);
}
{ // This DOES NOT COMPILE!
let mut client = Client {
sender: Wire,
packet: PhantomData,
};
let message = Text("Hello World!".to_string());
client.send(&message);
}
}
我将整个 Rust Playground上的代码放了进去。
我希望我能更好地描述我的问题,以便更好地搜索它,因此一旦我知道发生了什么,我会更改我的标题。
<A,B:Foo<A>>
这样内联它。 - Shepmasterwhere
(除了生命周期)。很高兴知道有一个标准的风格,我会很乐意遵循它。 - Michael Eden