- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 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/
我是一名优秀的程序员,十分优秀!