Rust 如何将尾部递归重写为一个循环?

Rust 如何将尾部递归重写为一个循环?,rust,Rust,我编写了前缀树的一个简单变体: struct Trie { data: Vec<Option<Trie>> } impl Trie { pub fn new() -> Trie { let mut data = Vec::with_capacity(26); for _ in 0..26 { data.push(None); } Trie { data: dat

我编写了前缀树的一个简单变体:

struct Trie {
    data: Vec<Option<Trie>>
}

impl Trie {
    pub fn new() -> Trie {
        let mut data = Vec::with_capacity(26);
        for _ in 0..26 {
            data.push(None);
        }
        Trie { data: data }
    }

    pub fn add(&mut self, word: &str) {
        if word.len() != 0 {
            let idx = Trie::char_idx(word.char_at(0));
            let word_suffix = word.slice_from(1);
            if self.data[idx].is_none() {
                self.data[idx] = Some(Trie::new());
            } 
            self.data[idx].as_mut().unwrap().add(word_suffix)
        }
    }

    pub fn contain(&self, word: &str) -> bool {
        if word.len() == 0 {
            true
        } else {
            match self.data[Trie::char_idx(word.char_at(0))] {
                Some(ref next) => next.contain(word.slice_from(1)),
                None => false 
            }
        }
    }

    fn char_idx(chr: char) -> usize {
        (chr as u32 - 97) as usize
    }
}

我能做些什么呢?

我记得我读过其他提出相同概念问题的问题,但我现在找不到它们。也许一个善良的灵魂会把他们联系在一起

话虽如此,本文汇编:

pub fn add(&mut self, word: &str) {
    let mut current = self; 
    for chr in word.chars() {
        current = {
            let tmp = current;
            let idx = Trie::char_idx(chr);
            if tmp.data[idx].is_none() {
                tmp.data[idx] = Some(Trie::new());
            }
            tmp.data[idx].as_mut().unwrap()
        }
    }
}
我的总体想法是围绕当前的事实展开工作。在for循环内部,我创建了一个新的词法作用域,然后将
current
重新加载为
tmp
。我们在
tmp
上进行工作,最终返回一个引用,然后将其放回
current

a似乎起到了作用:

pub fn add(&mut self, word: &str) {
    word.chars().fold(
        self,
        |current, chr| {
            let idx = Trie::char_idx(chr);
            if current.data[idx].is_none() {
                current.data[idx] = Some(Trie::new());
            }

            current.data[idx].as_mut().unwrap()
        });
}

更多的高尔夫。。。你不需要一个新的作用域,只要你把一些东西移回一个变量,你就可以在一个循环中离开它。此外,可变自参数:
pub fn add(&mut self, word: &str) {
    word.chars().fold(
        self,
        |current, chr| {
            let idx = Trie::char_idx(chr);
            if current.data[idx].is_none() {
                current.data[idx] = Some(Trie::new());
            }

            current.data[idx].as_mut().unwrap()
        });
}