Rust中自我和集合的易变性问题
我正在写一本锈迹斑斑的书,管理着一副纸牌。它具有洗牌、发牌等功能 函数的作用是:获取一个对self的可变引用,该引用允许重新洗牌现有的牌组。这应该非常简单:Rust中自我和集合的易变性问题,rust,mutability,Rust,Mutability,我正在写一本锈迹斑斑的书,管理着一副纸牌。它具有洗牌、发牌等功能 函数的作用是:获取一个对self的可变引用,该引用允许重新洗牌现有的牌组。这应该非常简单: 从包含一个带有卡片和随机数的元组的数据组中创建一个临时集合 按随机数对集合进行排序 使用临时集合的顺序重建现有层组 这方面的代码如下 pub struct Deck { // A deck contains zero or more cards cards: Vec<Card> } impl Deck { /
pub struct Deck {
// A deck contains zero or more cards
cards: Vec<Card>
}
impl Deck {
// shuffle
pub fn shuffle(&mut self) {
if self.cards.is_empty() {
return;
}
let mut shuffler : Vec<(&Card, u32)> = Vec::with_capacity(self.cards.len());
for card in self.cards.iter() {
// make a tuple consisting of each card in the input and a random number
let card_pos = (card, rand::thread_rng().gen::<u32>());
shuffler.push(card_pos);
}
// Sort the vector
shuffler.sort_by_key(|k| k.1);
// Clear the cards
self.cards.clear();
// Put the cards into the new randomized order
for card_pos in shuffler {
let (card, _) = card_pos;
self.cards.push(*card)
}
}
}
这些错误抱怨可变性,我认为这意味着它不喜欢我在范围内或其他地方有多个可变性引用,但我不知道如何修复它。我曾尝试使用大括号分隔符为每个动作生成块,但没有效果。我可能会把它分解成多个函数,但我宁愿它是一个函数。我如何以最少的努力完成这项工作
注意:我还没有测试排序功能,所以我希望“按键排序”功能符合我的想法,但这只有在我解决了第一个问题后才会起作用。
shuffler
属于Vec
类型,即卡是一个参考。也就是说,它是指向存储在self.cards
向量下面的缓冲区中的Card
对象的指针。所以self.cards.clear()
会删除shuffler
脚下的内存
幸运的是,有一个简单的解决方法:不要获取引用并清除向量,将卡移出self.cards
,使用drain
:
let mut shuffler: Vec<(Card, u32)> = Vec::with_capacity(self.cards.len());
for card in self.cards.drain(..) {
let card_pos = (card, rand::thread_rng().gen::<u32>());
shuffler.push(card_pos);
}
shuffler.sort_by_key(|k| k.1);
for card_pos in shuffler {
let (card, _) = card_pos;
self.cards.push(card);
}
let mut shuffler:Vec=Vec::with_capacity(self.cards.len());
对于自卡中的卡。卡。排液(…){
让card_pos=(card,rand::thread_rng().gen::());
洗牌器。推(卡片位置);
}
shuffler.sort_by_key(| k | k.1);
用于洗牌器中的卡牌位置{
let(card,u)=card_pos;
self.cards.push(卡片);
}
旁白:有一种就地洗牌算法,它比排序线性时间(而不是O(n logn))更有效,并且常数因子更好 shuffler
属于Vec
类型,即卡是一个参考。也就是说,它是指向存储在self.cards
向量下面的缓冲区中的Card
对象的指针。所以self.cards.clear()
会删除shuffler
脚下的内存
幸运的是,有一个简单的解决方法:不要获取引用并清除向量,将卡移出self.cards
,使用drain
:
let mut shuffler: Vec<(Card, u32)> = Vec::with_capacity(self.cards.len());
for card in self.cards.drain(..) {
let card_pos = (card, rand::thread_rng().gen::<u32>());
shuffler.push(card_pos);
}
shuffler.sort_by_key(|k| k.1);
for card_pos in shuffler {
let (card, _) = card_pos;
self.cards.push(card);
}
let mut shuffler:Vec=Vec::with_capacity(self.cards.len());
对于自卡中的卡。卡。排液(…){
让card_pos=(card,rand::thread_rng().gen::());
洗牌器。推(卡片位置);
}
shuffler.sort_by_key(| k | k.1);
用于洗牌器中的卡牌位置{
let(card,u)=card_pos;
self.cards.push(卡片);
}
旁白:有一种就地洗牌算法,它比排序线性时间(而不是O(n logn))更有效,并且常数因子更好 谢谢,成功了。我以前试过,没有使用裁判,我也遇到了其他类似的错误。我会记住洗牌算法,因为我可能会使它尽可能高效。谢谢,这就成功了。我以前试过,没有使用裁判,我也遇到了其他类似的错误。我会记住洗牌算法,因为我可能会尽可能使它高效。