2016-10-09 50 views
1

這個問題可能是非常基本的,但我甚至不知道要搜索什麼。 我沒有看到任何東西,在這本書中我跳了出來,我就是一個生鏽初學者:可變且不可變的數據訪問

struct Node; 
impl Node { 
    fn children(&mut self) -> &mut Vec<Node> { 
     // Pulls a field out of Node, to be mutated 
    } 
    fn next_node(&self) -> Node { 
     // Produces a new value using values computed from self. 
     // Doesn't hold a reference to self 
    } 
} 
[...] 
if self.children().len() > K { 
    let mut next_node = self.next_node(); 
    let list = self.children(); 
    // something involving next_node and list 
} 

這是我終於說服鏽病是我在做什麼是確定的。 我發現更直接的是:

let list = self.children(); 
if list.len() > K { 
    let mut next_node = self.next_node(); 
    // Something involving next_node and list 
} 

但它抱怨,因爲我無法在next_node得到一個不變的參考self,因爲已經有一個可變的一個在self.children追究起來,這是事實。

特別是在這個實現中,我只做了.children()一次,在這種情況下這不是一個非常複雜的方法,但可能是。

有沒有辦法做到這一點,它不會多次計算children,並且在不需要時不會構造next_node

回答

1

簡單的回答:沒有


鏽蝕能夠推理不相交的字段時借款,這樣你就可以借性情不定地一個字段,然後借另一領域,它會工作,只要這兩個發生在同樣的情況下(函數/方法) 。

在這種情況下,next_node對編譯器是不透明的,它可能實際上是我們所知的所有孩子。

因此,在撥打電話next_node時,要求未發生可變借款。


特別是在此實現我只做一次.children(),在這種情況下是不是一個很複雜的方法,但可能是。

確實......但這種方法的責任是什麼。爲什麼它會執行一個廣泛的計算借用?

這段代碼的簡單的組織將是:

  • 對於作爲一個小的作用域儘可能

做昂貴的計算一次(不借用)

  • 借它會工作:

    self.expensive_computation(); 
    
    if self.children.len() > K { 
        let mut next_node = self.next_node(); 
        let list = self.children; 
        // Something involving next_node and list 
    }