Rust 在包装函数中从结构借用内部数据
我一直在努力使一个库(Rust 在包装函数中从结构借用内部数据,rust,Rust,我一直在努力使一个库(rust websocket)使用更多的借阅和更少的拥有数据。这涉及到向结构添加一个Cow,这涉及到向该结构添加一个生存期,这使得整个库需要生存期 简而言之,我还有一个问题,我已经努力解决了好几天了。可以用以下代码进行总结: { // This works great! let mut sender = Wire; let message = Text("Hello World!".to_string()); sender.send_messag
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\u 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);
}
}
使用std::borrow::Cow;
使用std::iter::{Take,Repeat,Repeat};
使用std::marker::PhantomData;
特质发送者{
fn发送_数据包(&mut self,数据包:&P)->结果;
fn发送消息结果
其中M:Message{
数据:Cow消息>用于文本{
键入PacketIterator=Take-Take-Sender(&mut-self,packet:&packet(&mut-self,message:&m)->结果
其中M:Message将PhantomData
更改为PhantomData
。您的类型不存储p
,它在p
上运行
这里的问题是,您声称要存储一个p
,这意味着类型p
必须比类型客户端
更有效。对于p
(数据包类型)要使客户机
类型的生存时间更长,消息
本身必须比客户机
的生存时间更长,因为您从消息中借用数据包。但是,在这种情况下,客户机
比消息
的生存时间更长,因为客户机
是在堆栈上首先分配的(堆栈按相反的顺序拆下).你肯定是对的,但这是我不想要的行为,我应该更清楚。因为你指出的生命周期限制,所有消息都必须在创建客户端之前提前发出!我想要这些生命周期(客户端和消息)分开。有点离题,但我强烈建议您遵循where子句的Rust标准格式。我在扫描代码以查看泛型如何使用时遇到很多问题。我个人更喜欢总是使用where子句,而不是像
那样内联它。我也更喜欢where
(一生除外)。很高兴知道有一种标准样式,我很乐意遵循它。@Shepmaster改变了样式。