You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust遍历父向量时替换指定长度匹配切片的实现问题

问题

需要将Vec<u8>中所有匹配特定[u8;8]的8字节序列替换为目标[u8;8]数组,使用windows(8)遍历后编译器报错:the trait Sizedis not implemented for[u8]``,同时代码逻辑存在隐藏问题。

报错原因
  1. 类型不匹配:windows(8)返回的迭代器元素是&[u8]动态切片,即使长度固定为8,编译器也无法自动推导为固定大小数组;map闭包返回的[u8]切片无法直接被collect()转换为Vec<u8>——collect()需要的是单个u8元素的迭代器,而非切片整体。
  2. 逻辑错误:windows(8)是重叠遍历,比如长度13的Vec会生成6个重叠的8字节切片,直接map后collect会导致结果长度远超原数组,完全不符合替换需求。
解决方案

放弃windows迭代器,改用非重叠的遍历方式,逐个检查是否存在匹配的8字节序列,匹配则替换,否则保留原字节。

方案1:手动索引遍历(直观高效)

#[derive(Clone)]
struct Character {
    save_data: Vec<u8>,
}

fn main() {
    let source_character = Character {
        save_data: vec![3, 27, 22, 1, 1, 1, 1, 1, 1, 1, 1, 99, 27],
    };

    let mut result_character = source_character.clone();
    let source_steam_id: [u8; 8] = [1; 8];
    let target_steam_id: [u8; 8] = [2; 8];
    
    // 预分配内存,避免频繁扩容
    let mut new_save_data = Vec::with_capacity(result_character.save_data.len());
    let mut i = 0;
    let len = result_character.save_data.len();
    
    while i <= len {
        // 检查剩余长度是否足够容纳8字节,且匹配源ID
        if i + 8 <= len && result_character.save_data[i..i+8] == source_steam_id {
            new_save_data.extend_from_slice(&target_steam_id);
            i += 8; // 跳过已处理的8个字节
        } else if i < len {
            new_save_data.push(result_character.save_data[i]);
            i += 1; // 处理单个字节
        } else {
            break;
        }
    }
    
    result_character.save_data = new_save_data;
    dbg!(&result_character.save_data);
}

方案2:函数式迭代器写法

#[derive(Clone)]
struct Character {
    save_data: Vec<u8>,
}

fn main() {
    let source_character = Character {
        save_data: vec![3, 27, 22, 1, 1, 1, 1, 1, 1, 1, 1, 99, 27],
    };

    let mut result_character = source_character.clone();
    let source_steam_id: [u8; 8] = [1; 8];
    let target_steam_id: [u8; 8] = [2; 8];
    
    let mut new_save_data = Vec::with_capacity(result_character.save_data.len());
    let mut skip_count = 0;

    result_character.save_data.iter().enumerate().for_each(|(idx, &byte)| {
        if skip_count > 0 {
            skip_count -= 1;
            return;
        }
        // 检查是否匹配8字节序列
        if idx + 8 <= result_character.save_data.len() 
            && result_character.save_data[idx..idx+8] == source_steam_id
        {
            new_save_data.extend_from_slice(&target_steam_id);
            skip_count = 7; // 已处理当前字节,剩余7个跳过
        } else {
            new_save_data.push(byte);
        }
    });
    
    result_character.save_data = new_save_data;
    dbg!(&result_character.save_data);
}
关键说明
  • 两种方案均避免了重叠遍历,确保结果长度与原数组一致;
  • 使用extend_from_slice直接添加目标数组,避免不必要的内存拷贝;
  • 预分配内存Vec::with_capacity提升性能。

内容的提问来源于stack exchange,提问作者noconst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:43:08