如何在Rust中每次提取GPS数据后自动更新切片范围?
解决GPS数据切片自动更新的问题
要实现每次提取Token后自动更新切片范围,核心是让提取函数同时返回提取到的Token和剩余的切片,后续调用基于新切片继续处理即可。以下是完整的修正实现:
修改后的代码
fn get_string_token(mut buff: &[u8], delimiter: u8) -> Result<(String, &[u8]), ()> { // 定位分隔符位置 match buff.iter().position(|&ch| ch == delimiter) { Some(index) => { // 提取当前Token let token_slice = &buff[0..index]; let token = String::from_utf8_lossy(token_slice).to_string(); // 更新切片:跳过当前分隔符,指向剩余数据 buff = &buff[index + 1..]; Ok((token, buff)) } None => { // 处理最后一个字段(无后续分隔符) let token = String::from_utf8_lossy(buff).to_string(); Ok((token, &[])) } } } fn extract_data(mut buff: &[u8]) { // 第一次提取:$GNGGA let (token, remaining) = get_string_token(buff, b',').unwrap(); buff = remaining; println!("第一个字段: {}", token); // 第二次提取:062735.00 let (token, remaining) = get_string_token(buff, b',').unwrap(); buff = remaining; println!("第二个字段: {}", token); // 第三次提取:3150.788156 let (token, remaining) = get_string_token(buff, b',').unwrap(); buff = remaining; println!("第三个字段: {}", token); // 可继续提取后续字段... } fn main() { // 模拟填充GPS数据到缓冲区 let gps_data = b"$GNGGA,062735.00,3150.788156,N,11711.922383,E,1,12,2.0,90.0,M,,M,,*55"; let mut buff: [u8; 1024] = [0; 1024]; buff[..gps_data.len()].copy_from_slice(gps_data); extract_data(&buff[..gps_data.len()]); }
关键修改说明
- 返回值调整:将原函数的
Result<String, ()>改为Result<(String, &[u8]), ()>,每次提取后同时返回Token和剩余切片,实现自动更新范围。 - 切片更新逻辑:找到分隔符后,直接将切片指向
buff[index + 1..],跳过当前分隔符,确保下一次提取从新位置开始。 - 空字段兼容:移除原代码中
end_index - start_index >1的判断,保留NMEA协议中空字段(如,,)的提取,返回空字符串符合协议规则。 - 末尾字段处理:当找不到分隔符时,直接提取剩余全部数据作为最后一个字段,避免遗漏。
批量提取优化
如果需要一次性提取所有字段,可通过循环简化代码:
fn extract_all_fields(mut buff: &[u8]) -> Vec<String> { let mut fields = Vec::new(); loop { match get_string_token(buff, b',') { Ok((token, remaining)) => { fields.push(token); if remaining.is_empty() { break; } buff = remaining; } Err(_) => break, } } fields }
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

