我一直在慢慢地教自己一些Rust,在我最近的奋进中,我正在尝试在Rust中实现一些Maelstrom“工作负载”。
作为Broadcast“工作负载”的一部分,我试图跟踪其他“节点”知道的消息列表,并只返回一组它们不知道的消息,加上一些随机的额外消息(以防某些消息被“丢弃”或其他情况)。)...
但我遇到了一些我无法理解的怪事。下面是我正在尝试做的事情的一个片段(完整源代码在这里):
// start by getting all the values we know the src node doesn't know
let src_known = self.neighbors_known_msgs.get(&msg.src).unwrap(); // this ends up being a HashSet<usize> (already checked it exists earlier in method)
let mut src_unknown: HashSet<_> = self.known_msgs
.difference(src_known)
.copied()
.collect();
// Now extend that list with an extra set of values
let list:Vec<_> = self.known_msgs.iter().copied().collect();
let mut window_size = MIN_WIDOWING_SIZE.max(list.len()/5);
window_size = window_size.min(list.len());
// for a first pass, just select the extras randomly,
// before trying to implement proper windowing
let mut rng = rand::thread_rng();
let extras = (0..=window_size).filter_map(|_| {
let idx: usize = rng.gen();
list.get(idx)
}).cloned();
// at this point, we have a list of 20% of of the
// total messages we know about in the 'extras' range/iterator
src_unknown.extend(extras);
// `src_unknown` is unchanged at this point...???
// and `extras` is not exhausted...???
我设置了一个测试,其中self.known_msgs
和self.neighbors_known_msgs.get(&msg.src)
具有完全相同的100个值的集合,因此.difference(..)
导致没有值的集合。
因此,我希望extras
有20个值(在debug中显示),在src_unknown.extend(extras);
语句执行后,src_unknown
中只有这些值……
但实际结果是src_unknown
没有变化,extras
仍然是Cloned<FilterMap<RangeInclusive<usize>
,在调试器中显示iter:{start:0, end:20, exhausted:false}
...??
我不明白这里出了什么问题...救命!(提前感谢!))
1条答案
按热度按时间bejyjqdl1#
看看这条线。
这将创建一个随机
usize
。例如,这里有10个随机的usize
值。一个随机的
usize
小于100的概率只有0.000000000005%,所以如果你用它来索引一个长度为100的列表,它几乎永远不会在边界内。因此,您创建的是一个筛选器,它可以看到21个None
值,然后完成。要获得想要的行为,可以使用
SliceRandom::choose
。但是,如果你不想要重复的元素,你可以使用
choose_multiple
。