如何初始化一片 HashMap?
How do I initialize a slice of HashMaps?
我有一种情况需要 HashMap 的切片,切片的长度由一个常量指定。怎么初始化这样的野兽?
use std::collections::HashMap;
use std::default::Default;
const LENGTH: usize = 10;
fn main() {
let f: [HashMap<String, u32>; LENGTH] = ???;
}
我已经尝试了 ???现货:
Default::default()
[HashMap::new(); LENGTH]
[Default::default(); LENGTH]
iter::repeat(HashMap::new()).take(LENGTH).collect().as_slice()
每一个都给我不同的错误:
test.rs:7:45: 7:61 error: the trait `core::default::Default` is not implemented for the type `[std::collections::hash::map::HashMap<collections::string::String, u32>; 10]` [E0277]
test.rs:7 let f: [HashMap<String, u32>; LENGTH] = Default::default();
^~~~~~~~~~~~~~~~
test.rs:7:45: 7:69 error: the trait `core::marker::Copy` is not implemented for the type `std::collections::hash::map::HashMap<collections::string::String, u32>` [E0277]
test.rs:7 let f: [HashMap<String, u32>; LENGTH] = [HashMap::new(); LENGTH];
^~~~~~~~~~~~~~~~~~~~~~~~
test.rs:7:45: 7:73 error: the trait `core::marker::Copy` is not implemented for the type `std::collections::hash::map::HashMap<collections::string::String, u32>` [E0277]
test.rs:7 let f: [HashMap<String, u32>; LENGTH] = [Default::default(); LENGTH];
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.rs:8:45: 8:107 error: the type of this value must be known in this context
test.rs:8 let f: [HashMap<String, u32>; LENGTH] = iter::repeat(HashMap::new()).take(LENGTH).collect().as_slice();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这里有什么我遗漏的特殊魔法吗?还是我遇到了错误?
它不是切片,而是固定大小的数组。
您不能创建包含某些内容的切片,因为切片只是对属于其他内容(如数组或向量)的内存的“视图”。
Rust < 1.52 中的固定大小数组通常没有用。那是因为 Rust 还不支持带有整数参数的泛型类型,但是 Rust 中几乎所有的东西都是作为特征(泛型)实现的,所以它们不适用于数组。
您需要使用 Vec
。
使用MaybeUninit
是我能想到的最好的方法。它的文档中有完全相同的内容:initializing-an-array-element-by-element.
use std::collections::HashMap;
use std::mem::{MaybeUninit, transmute};
const LENGTH: usize = 10;
fn main() {
let _data: [HashMap<String, u32>; LENGTH] = {
let mut data: [MaybeUninit<HashMap<String, u32>>; LENGTH] = unsafe {
MaybeUninit::uninit().assume_init()
};
for elem in &mut data[..] {
*elem = MaybeUninit::new(HashMap::new());
}
unsafe { transmute::<_, [HashMap<String, u32>; LENGTH]>(data) }
};
}
我有一种情况需要 HashMap 的切片,切片的长度由一个常量指定。怎么初始化这样的野兽?
use std::collections::HashMap;
use std::default::Default;
const LENGTH: usize = 10;
fn main() {
let f: [HashMap<String, u32>; LENGTH] = ???;
}
我已经尝试了 ???现货:
Default::default()
[HashMap::new(); LENGTH]
[Default::default(); LENGTH]
iter::repeat(HashMap::new()).take(LENGTH).collect().as_slice()
每一个都给我不同的错误:
test.rs:7:45: 7:61 error: the trait `core::default::Default` is not implemented for the type `[std::collections::hash::map::HashMap<collections::string::String, u32>; 10]` [E0277]
test.rs:7 let f: [HashMap<String, u32>; LENGTH] = Default::default();
^~~~~~~~~~~~~~~~
test.rs:7:45: 7:69 error: the trait `core::marker::Copy` is not implemented for the type `std::collections::hash::map::HashMap<collections::string::String, u32>` [E0277]
test.rs:7 let f: [HashMap<String, u32>; LENGTH] = [HashMap::new(); LENGTH];
^~~~~~~~~~~~~~~~~~~~~~~~
test.rs:7:45: 7:73 error: the trait `core::marker::Copy` is not implemented for the type `std::collections::hash::map::HashMap<collections::string::String, u32>` [E0277]
test.rs:7 let f: [HashMap<String, u32>; LENGTH] = [Default::default(); LENGTH];
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.rs:8:45: 8:107 error: the type of this value must be known in this context
test.rs:8 let f: [HashMap<String, u32>; LENGTH] = iter::repeat(HashMap::new()).take(LENGTH).collect().as_slice();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这里有什么我遗漏的特殊魔法吗?还是我遇到了错误?
它不是切片,而是固定大小的数组。
您不能创建包含某些内容的切片,因为切片只是对属于其他内容(如数组或向量)的内存的“视图”。
Rust < 1.52 中的固定大小数组通常没有用。那是因为 Rust 还不支持带有整数参数的泛型类型,但是 Rust 中几乎所有的东西都是作为特征(泛型)实现的,所以它们不适用于数组。
您需要使用 Vec
。
使用MaybeUninit
是我能想到的最好的方法。它的文档中有完全相同的内容:initializing-an-array-element-by-element.
use std::collections::HashMap;
use std::mem::{MaybeUninit, transmute};
const LENGTH: usize = 10;
fn main() {
let _data: [HashMap<String, u32>; LENGTH] = {
let mut data: [MaybeUninit<HashMap<String, u32>>; LENGTH] = unsafe {
MaybeUninit::uninit().assume_init()
};
for elem in &mut data[..] {
*elem = MaybeUninit::new(HashMap::new());
}
unsafe { transmute::<_, [HashMap<String, u32>; LENGTH]>(data) }
};
}