get() 函数不会在元组键上产生任何结果,并且值存在并且在手动检查时确实匹配
get() function doesn't yield any result on tuple keys, and the values exist and do match when manually checked
let mut FEED_CA_:HashMap<(Address, Address, Address), (iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>)> = HashMap::new();
for i in FEED_CA_START{
let c0 = i[0];
let c1 = i[1];
let c2 = i[2];
let p_01_ = ALL_C.get(&&(*c0, *c1)).ok_or(continue).unwrap();
FEED_CA_START
是 (c0, c1, c2) 元组的 vec :)
ALL_C
是 <(Address, Address), Address> 的 HashMap,我无法从中获取值。
整个迭代在上面代码段的最后一行失败。还有八个 get()
s,但没有一个被填充,我在遍历整个数据库后插入结果的输出数据结构 (FEED_CA_
) 总是 len = 0
。
我已经:
打印出元组 FEED_CA_START
中每个 i
的值 &(c0, c1)
打印出错误的值&(c0, c1)
,还有&(*c0, *c1)
甚至&&(*c0, *c1)
.
手动发现它们确实匹配,确实存在(100% 的调用应该成功)。
打印出上面的类型并确保它们确实匹配。结果相同,即使查询和键的类型匹配并且都完全相同:&(primitive_types::H160, primitive_types::H160)
做了一些borrow&deref的试错组合,能试的就这么多,还是没希望。
打印出我从中导出的数据库并手动检查 - 有多个匹配项,程序 returns 总是正好为 0,我已经尝试了多个 functions/methods/iterations,我的程序总是在get()
函数处中断,直接继续
I 运行 一个简单的测试,在一个新程序中,我创建了一个 HashMap,其地址类似于 ALL_C
,并使用元组键访问它 - 然后有效。这里没有。我什至在那里扔了一些 reference/typing 意大利面条以确保它也破裂,但没有。每次都得到价值。在这里,我尽我所能使它工作,这是第 2 天卡在这个问题上,死胡同。
我该如何处理这样的问题?我迷路了。
如果我理解的代码片段是正确的,我认为你的问题是 .ok_or(continue)
。
Arguments passed to ok_or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use ok_or_else, which is lazily evaluated.
换句话说,continue
总是被求值,因此代码确实没有按照您的预期进行。
let p_01_ = ALL_C.get(&(c0, c1)).ok_or(continue).unwrap();
println!("unreachable");
作为一种可能的解决方案,您可以使用 filter_map
,它会忽略所有 None
结果,然后检查长度。它看起来不是很优雅,但重复 if let
块可能会更好:
// Note: I just guessed some types for an example
for i in FEED_CA_START {
let c0 = i.0;
let c1 = i.1;
let c2 = i.2;
let args = vec![(c0, c1), (c0, c2)];
let ps: Vec<&Address> = args.iter().filter_map(|arg| ALL_C.get(arg)).collect();
if ps.len() != args.len() {
continue;
}
// Do something
}
根据另一个答案,continue
被评估,因此它永远不会检查其他代码。 IMO 应该不可能首先构建它。
另一方面,这样做不是一个好的构造,您应该使用更生锈的东西,例如:
let mut FEED_CA_:HashMap<(Address, Address, Address), (iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>)> = HashMap::new();
for i in FEED_CA_START{
let c0 = i[0];
let c1 = i[1];
let c2 = i[2];
if let Some(p_01_) = ALL_C.get(&&(*c0, *c1)) {
// compute stuff over `p_01_`
} else { // else could be avoided if you don't need to compute anything else in the loop if there is nothing for the key
continue
};
...
let mut FEED_CA_:HashMap<(Address, Address, Address), (iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>)> = HashMap::new();
for i in FEED_CA_START{
let c0 = i[0];
let c1 = i[1];
let c2 = i[2];
let p_01_ = ALL_C.get(&&(*c0, *c1)).ok_or(continue).unwrap();
FEED_CA_START
是 (c0, c1, c2) 元组的 vec :)
ALL_C
是 <(Address, Address), Address> 的 HashMap,我无法从中获取值。
整个迭代在上面代码段的最后一行失败。还有八个 get()
s,但没有一个被填充,我在遍历整个数据库后插入结果的输出数据结构 (FEED_CA_
) 总是 len = 0
。
我已经:
打印出元组
中每个FEED_CA_START
i
的值&(c0, c1)
打印出错误的值
&(c0, c1)
,还有&(*c0, *c1)
甚至&&(*c0, *c1)
.手动发现它们确实匹配,确实存在(100% 的调用应该成功)。
打印出上面的类型并确保它们确实匹配。结果相同,即使查询和键的类型匹配并且都完全相同:
&(primitive_types::H160, primitive_types::H160)
做了一些borrow&deref的试错组合,能试的就这么多,还是没希望。
打印出我从中导出的数据库并手动检查 - 有多个匹配项,程序 returns 总是正好为 0,我已经尝试了多个 functions/methods/iterations,我的程序总是在
get()
函数处中断,直接继续I 运行 一个简单的测试,在一个新程序中,我创建了一个 HashMap,其地址类似于
ALL_C
,并使用元组键访问它 - 然后有效。这里没有。我什至在那里扔了一些 reference/typing 意大利面条以确保它也破裂,但没有。每次都得到价值。在这里,我尽我所能使它工作,这是第 2 天卡在这个问题上,死胡同。
我该如何处理这样的问题?我迷路了。
如果我理解的代码片段是正确的,我认为你的问题是 .ok_or(continue)
。
Arguments passed to ok_or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use ok_or_else, which is lazily evaluated.
换句话说,continue
总是被求值,因此代码确实没有按照您的预期进行。
let p_01_ = ALL_C.get(&(c0, c1)).ok_or(continue).unwrap();
println!("unreachable");
作为一种可能的解决方案,您可以使用 filter_map
,它会忽略所有 None
结果,然后检查长度。它看起来不是很优雅,但重复 if let
块可能会更好:
// Note: I just guessed some types for an example
for i in FEED_CA_START {
let c0 = i.0;
let c1 = i.1;
let c2 = i.2;
let args = vec![(c0, c1), (c0, c2)];
let ps: Vec<&Address> = args.iter().filter_map(|arg| ALL_C.get(arg)).collect();
if ps.len() != args.len() {
continue;
}
// Do something
}
根据另一个答案,continue
被评估,因此它永远不会检查其他代码。 IMO 应该不可能首先构建它。
另一方面,这样做不是一个好的构造,您应该使用更生锈的东西,例如:
let mut FEED_CA_:HashMap<(Address, Address, Address), (iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>, iuniswapv2pair_mod::IUniswapV2Pair<Provider<Ws>>)> = HashMap::new();
for i in FEED_CA_START{
let c0 = i[0];
let c1 = i[1];
let c2 = i[2];
if let Some(p_01_) = ALL_C.get(&&(*c0, *c1)) {
// compute stuff over `p_01_`
} else { // else could be avoided if you don't need to compute anything else in the loop if there is nothing for the key
continue
};
...