gpt4 book ai didi

rust - 处理 rust 中泛型和非泛型类型的枚举返回

转载 作者:行者123 更新时间:2023-12-04 07:27:28 33 4
gpt4 key购买 nike

我正在尝试在 Rust 中创建 strip 化的 redis 克隆。我在尝试实现 redis 协议(protocol)时遇到了困难。
我想要一个结构来封装传入的数据包并将其适本地解析为它的数据类型和命令。
我的数据类型是简单的字符串或整数,但对于我想使用的数组数据类型有一点不同 Vec<T>这就是我的问题开始的地方。
所以我创建了代表我传入数据包的结构。
想要用这个结构存档什么才能做到:let parsed_value = ProtocolPacket::new(data: &[u8])

struct ProtocolPacket <T> {  //  <-- this <T> is only because of ProtocolPacketData<T>
command: ProtocolPacketCommand,
data: ProtocolPacketData<T>,
}
impl <T>ProtocolPacket <T> {
fn new(packet: &[u8]) -> ProtocolPacket<T> {
let packet = packet.into_iter();
let command = ProtocolPacketCommand::new(packet.next().unwrap()); // <-- This is working
// Delete \r \n
packet.next_back().unwrap();
packet.next_back().unwrap();

let data = packet.as_slice();
let data = ProtocolPacketData::new(data);


ProtocolPacket{
command: command,
data: data,
}
}
enum ProtocolPacketData <T> {
SimpleString(String),
Error(String),
Integer(i64),
String(String),
Array(Vec<T>),
}

impl <T> ProtocolPacketData <T> {
pub fn new(rest: &[u8]) -> ProtocolPacketData<T> {
let rest = rest.into_iter();
let data_type = rest.next().unwrap();

// Strip last 2 bytes -> \r\n
rest.next_back().unwrap();
rest.next_back().unwrap();

match data_type.to_string().chars().next().unwrap() {
'+' => handle_packet_simplestring(rest.as_slice()), <-- Function call that returns ProtocolPacketData<String>
'-' => unimplemented!()
':' => unimplemented!()
'$' => unimplemented!()
'*' => unimplemented!()
'%' => unimplemented!()
_ => unimplemented!()
}
}
}


fn handle_packet_simplestring<T>(packet_value: &[u8]) -> ProtocolPacketData<String>{
let data = String::from_utf8_lossy(packet_value);
ProtocolPacketData::SimpleString(data.to_string())
}
这是我的错误发生的地方
    match data_type.to_string().chars().next().unwrap() {
'+' => handle_packet_simplestring(rest.as_slice()), <-- Function call that returns ProtocolPacketData<String>
'-' => unimplemented!()
':' => unimplemented!()
'$' => unimplemented!()
'*' => unimplemented!()
'%' => unimplemented!()
_ => unimplemented!()
}
我收到一个错误
mismatched types
expected enum ProtocolPacketData<T>
found enum ProtocolPacketData<std::string::String>
我怎样才能完成这项工作,这甚至是可行的方法吗?
谢谢,山姆

最佳答案

问题是您实际上是在对编译器撒谎。 impl<T> ProtocolPacketData<T>表示 ProtocolPacketData<T> 的“外部”可以决定任何它想要的T成为和那个impl必须申请。例如一个应该能够做到let x: ProtocolPacketData::<f64> = ProtocolPacketData::new(&buffer) ;但是 handle_packet_simplestring然后放一个 String在哪里 f64必须。编译器试图告诉你:它需要一个 ProtocolPacketData<T> - 对 T 没有限制- 但你返回了一个特定的 ProtocolPacketData<String> (由于 unimplemented!() 返回 ! ,因此其他匹配项强制执行此操作,因此编译器得出结论,在任何情况下它都必须是 String,而不管 T )。
您可能想删除 T - 完全参数并扩展ProtocolPacketData

enum ProtocolPacketData {
// ...
StringArray(Vec<Box<str>>),
IntArray(Vec<u64>),
// ...
}
和你的大 match返回一个特定的变体。
另一种可能是
enum ProtocolPacketData {
// ...
Array(Vec<ProtocolPacketData>),
}
这使得 Array变体更简单;但它允许异构数组 ( [Integer, String, Array[String, String]]),这可能不是您想要的。

关于rust - 处理 rust 中泛型和非泛型类型的枚举返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68136304/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com