如何在Rust结构体中存储任意大小的字节数组?
问题代码与错误信息
原始代码
struct Pack { data: Box<[u8]> } fn foo() { let mut p = Pack { data: Box::new(**b"Hello!") }; p.data.set(b"Bye!"); }
编译错误
error[E0614]: type `[u8; 6]` cannot be dereferenced --> foo | 30 | data: Box::new(**b"Hello!") | ^^^^^^^^^^^ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> foo | 30 | data: Box::new(**b"Hello!") | ^^^^^^^^ doesn't have a size known at compile-time |
错误原因分析
- 非法解引用:
b"Hello!"是&[u8; 6]类型(固定长度字节数组的引用),第一次解引用*b"Hello!"得到[u8;6](固定大小数组),而Rust中固定大小数组不支持二次解引用,因此**b"Hello!"是无效操作。 - 类型转换错误:
Box::new要求传入编译期大小已知的类型(实现Sizedtrait),即便去掉一次解引用,Box::new(*b"Hello!")得到的是Box<[u8;6]>,无法直接隐式转为Box<[u8]>(动态切片的装箱类型)。 - 方法不存在:
Box<[u8]>没有内置的set方法,需要用Rust原生的方式修改内容。
正确实现方式
方式1:替换整个动态切片
如果需要完全替换data的内容,直接重新赋值即可,同时修正初始化逻辑:
struct Pack { data: Box<[u8]> } fn foo() { // 用Box::from直接将字节数组引用转为Box<[u8]> let mut p = Pack { data: Box::from(b"Hello!") }; // 重新赋值为新的动态切片装箱 p.data = Box::from(b"Bye!"); }
方式2:修改现有切片内容(长度需一致)
如果仅需修改现有切片的字节内容,且新内容长度与原切片相同,可使用copy_from_slice方法:
struct Pack { data: Box<[u8]> } fn foo() { let mut p = Pack { data: Box::from(b"Hello!") }; // 确保新内容长度与原切片一致(此处均为6字节) p.data.copy_from_slice(b"Bye!!!"); }
初始化的其他可选方式
除了Box::from,还可以通过Vec中转实现类型转换:
// 先转为Vec<u8>,再转成Box<[u8]> data: b"Hello!".to_vec().into_boxed_slice()
内容的提问来源于stack exchange,提问作者yegor256
相关产品推荐
相关产品推荐

