哈希映射宏拒绝类型检查,失败并显示误导性(且看似错误)错误消息?



我这里有这两个相关的宏:

#[macro_export]
macro_rules! hash_map {
( $( $key:expr => $value:expr ),* ) => {
{
use ::std::iter::FromIterator;
::std::collections::HashMap::from_iter(&[$(($key, $value)),*])
}
};
}
#[macro_export]
macro_rules! hash_set {
( $( $x:expr ),* ) => {
{
use ::std::iter::FromIterator;
::std::collections::HashSet::from_iter(&[$($x),*])
}
};
}

我主要在测试中使用它,如下所示:

assert!(foo.one == hash_map!{});
assert!(foo.two == hash_set![String::from("some value")]);

但是出于某种原因,我从中得到了一条非常误导和荒谬的错误消息:

error[E0271]: type mismatch resolving `<&[_; 0] as std::iter::IntoIterator>::Item == (_, _)`
--> src/common.rs:M:N
|
6   |             ::std::collections::HashMap::from_iter(&[$(($key, $value)),*])
|             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found tuple
| 
::: src/foo.rs:M:N
|
154 |         assert!(foo.one == hash_map!{});
|                                         ----------- in this macro invocation
|
= note: expected type `&_`
found type `(_, _)`
= note: required by `std::iter::FromIterator::from_iter`
error[E0308]: mismatched types
--> src/common.rs:M:N
|
16  |             ::std::collections::HashSet::from_iter(&[$($x),*])
|             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found reference
| 
::: src/foo.rs:M:N
|
150 |     fn it_can_do_things() {
|                                - help: try adding a return type: `-> std::collections::HashSet<&std::string::String, _>`...
155 |         assert!(foo.two == hash_set![String::from("some value")]);
|                                  -------------------------------------------- in this macro invocation
|
= note: expected type `std::collections::HashSet<std::string::String, std::collections::hash_map::RandomState>`
found type `std::collections::HashSet<std::string::String, std::collections::hash_map::RandomState>`
found type `std::collections::HashSet<&std::string::String, _>`

我尝试将元组本身作为第一个引用,但这没有帮助。

error[E0271]: type mismatch resolving `<&[_; 0] as std::iter::IntoIterator>::Item == (_, _)`
--> src/common.rs:M:N
|
6   |             ::std::collections::HashMap::from_iter(&[$(&($key, $value)),*])
|             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found tuple
| 
::: src/foo.rs:M:N
|
154 |         assert!(foo.one == hash_map!{});
|                                         ----------- in this macro invocation
|
= note: expected type `&_`
found type `(_, _)`
= note: required by `std::iter::FromIterator::from_iter`

我的目标是尝试让哈希映射保留并在单个批次中添加所有内容,但我无法让它正常工作。请注意,我正在创建的哈希映射/集合拥有其值。

最少的复制:

fn main() {
use std::collections::HashMap;
use std::iter::FromIterator;
let _ = HashMap::from_iter([("key", "value")].iter());
}

您必须遍历拥有的元组,而不是借用的元组,因此出现奇怪的错误消息:

fn main() {
use std::collections::HashMap;
use std::iter::FromIterator;
let _: HashMap<_, _> = HashMap::from_iter([("key", "value")].iter().cloned());
}

您也可以按照FromIterator文档中的说明使用collect

FromIteratorfrom_iter很少被显式调用,而是通过Iteratorcollect方法使用。有关更多示例,请参阅collect的文档。

fn main() {
use std::collections::HashMap;
let _: HashMap<_, _> = [("key", "value")].iter().cloned().collect();
// or
let _: HashMap<_, _> = vec![("key", "value")].into_iter().collect();
}

请注意,错误消息更容易理解collect

error[E0277]: the trait bound `std::collections::HashMap<_, _>: std::iter::FromIterator<&(&str, &str)>` is not satisfied
--> src/main.rs:4:54
|
4 |     let _: HashMap<_, _> = [("key", "value")].iter().collect();
|                                                      ^^^^^^^ a collection of type `std::collections::HashMap<_, _>` cannot be built from an iterator over elements of type `&(&str, &str)`
|
= help: the trait `std::iter::FromIterator<&(&str, &str)>` is not implemented for `std::collections::HashMap<_, _>`

最后一行更有帮助:迭代器必须遍历元组而不是对元组的引用:

impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S> 

最新更新