未实现Copy trait的结构体如何存入数组?vec!为何可行?
Rust数组与vec!宏的差异及解决方案
问题场景
定义结构体:
#[derive(Clone)] struct Bar {}
用数组字面量创建实例数组时编译失败:
let v : [Bar; 10] = [Bar {}; 10]; assert_eq!(10, v.len());
错误提示:the trait Copyis not implemented forBar``
但使用vec!宏却能正常运行:
let v = vec![Bar {}; 10]; assert_eq!(10, v.len());
一、vec!宏的内部处理逻辑
vec![x; n]的行为分两种情况:
- 当
x实现Copy时,直接按位复制n份; - 当
x只实现Clone时,宏会先创建一个x的初始实例,然后调用clone()方法复制n-1次,把所有实例放进预先分配好的内存里。
你的Bar实现了Clone,所以vec!会走第二种逻辑,不需要Copy trait就能生成多个实例。
二、数组实现同样效果的方法
Rust的数组字面量[x; n]在编译期工作,要求元素必须Copy,要绕开这个限制可以用以下几种方式:
1. 给Bar实现Copy trait
如果Bar没有持有堆内存或需要手动管理的资源,直接派生Copy即可:
#[derive(Clone, Copy)] struct Bar {} let v : [Bar; 10] = [Bar {}; 10]; // 编译通过
2. 使用from_fn创建数组(Rust 1.63+)
core::array::from_fn可以通过闭包生成每个元素,既可以直接创建新实例,也可以克隆同一个实例:
#[derive(Clone)] struct Bar {} // 直接创建10个新的Bar实例 let v: [Bar; 10] = core::array::from_fn(|_| Bar {}); // 克隆同一个原始实例 let original = Bar {}; let v: [Bar; 10] = core::array::from_fn(|_| original.clone());
3. 迭代器转数组(Rust 1.55+)
用迭代器生成元素,再转换为数组,缺点是会先创建Vec再转,效率略低:
#[derive(Clone)] struct Bar {} let v: [Bar; 10] = std::iter::repeat(Bar {}) .take(10) .collect::<Vec<_>>() .try_into() .unwrap();
4. 手动初始化(适合短数组)
如果数组长度不大,直接逐个写出来最直接:
#[derive(Clone)] struct Bar {} let v = [Bar {}, Bar {}, Bar {}, Bar {}, Bar {}, Bar {}, Bar {}, Bar {}, Bar {}, Bar {}];
内容的提问来源于stack exchange,提问作者yegor256
相关产品推荐
相关产品推荐

