无法推断结构中泛型类型参数的类型



作为一个更大项目的一部分,我目前正在尝试在rust中实现base64编码/解码,并且需要一个数据结构来将base64字符集映射到ASCII,反之亦然。我在这个StackOverflow答案中找到了双向HashMap的基本实现,但由于我需要base64映射作为全局变量,以便编码/解码函数都能访问它,所以我不能一个接一个地添加字符映射。因此,我在BidiMap实现中添加了另一个函数,该函数在一批中完成(其他函数实现与上面的链接相同(:

impl<A, B> BidiMap<A, B>
where
A: Eq + Hash,
B: Eq + Hash,
{
// ...
pub fn from_array_with_u8_indices(values: &[B]) -> BidiMap<u8, B>
where B: Copy,
{
if values.len() > u8::MAX as usize + 1 {
panic!("This function should only be called with an array whose indices fit into an u8.");
}
let mut map: BidiMap<u8, B> = BidiMap::new();
for i in 0..values.len() {
map.insert(i as u8, values[i]);
}
map
}
// ...
}

然后我在另一个文件base64.rs:中调用这个函数

use crate::datastructures::bidi_map::BidiMap;
const base64_values: [u8; 65] = [
0x41, 0x42, 0x43, ... , 0x3D,
];
const base64_map: BidiMap<u8, u8> = BidiMap::from_array_with_u8_indices(&base64_values);

但是当我试图编译这个代码时,我得到了错误

error[E0282]: type annotations needed
--> src/encodings/base64.rs:10:37
|
10 | const base64_map: BidiMap<u8, u8> = BidiMap::from_array_with_u8_indices(&base64_values);
|                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `A`

尽管我用BidiMap<u8, u8>指定了AB的类型。我对rust和泛型编程还很陌生,所以可能我错过了一些非常明显的东西,但我不知道这个问题的解决方案是什么。我已经尝试更改函数签名和实现,以返回Self而不是BidiMap<u8, B>,但随后它抱怨在调用CCD_ 9时无法将数组索引强制转换为泛型类型CCD_。

这里是一个重现问题的最小示例。

正如您所指出的,from_array_with_u8_indices返回类型确实是正确推断的。

但是,无法推断BidiMap::from_array_with_u8_indices具体类型,因为该方法是为BidiMap<A, B>实现的。返回类型与此类型无关。

两种可能的修复方法:

使用Turbo fish语法明确指定具体类型:

let map = BidiMap::<u8, u8>::from_array_with_u8_indices(&base64_values);

为您知道要返回的类型创建一个特定的实现:

impl<B> BidiMap<u8, B>
where
B: Eq + Hash,
{
pub fn from_array_with_u8_indices(values: &[B]) -> Self
where
B: Copy,
{
let mut map: BidiMap<u8, B> = BidiMap::new();
//...
map
}
}

在这种情况下,您根本不需要指定类型:

let base64_map = BidiMap::from_array_with_u8_indices(&base64_values);

操场中的工作代码示例

最新更新