2016-11-03 49 views
0

在C,這是常見的分配和在一個單一的表達比較:可能將表達式中的賦值和比較結合起來?

n = n_init; 
do { 
    func(n); 
} while ((n = n.next) != n_init); 

據我所知,這可以在拉斯特表示爲:

n = n_init; 
loop { 
    func(n); 
    n = n.next; 
    if n == n_init { 
     break; 
    } 
} 

其中一期工程相同,C版(假設循環的主體不使用continue)。

有沒有一種更簡潔的方式來表達這在鏽,或者是上述理想的例子?

爲了這個問題的目的,假設所有權或滿足借用檢查器不是問題。開發人員需要滿足這些要求。

例如,作爲一個整數:

n = n_init; 
loop { 
    func(&vec[n]); 
    n = vec[n].next; 
    if n == n_init { 
     break; 
    } 
} 

這似乎是顯而易見的是生鏽的例子是地道的防鏽 - 但是我期待了很多這種風格環路的移動生鏽,我m有興趣知道是否有更好/不同的表達方式。

+0

我會考慮將模式包裝到一個迭代器中,所以你可以這樣做:'for some_iter(n_init){func(n)}' –

+2

請你發佈完整的例子。每次發佈代碼片段時,我們都必須猜測涉及的類型可能是什麼。他們是「複製」嗎?他們擁有某種東西嗎?我們不知道!我們不知道! –

+0

@Matthieu M對能夠表達什麼類型的流量控制感興趣,我不想在我的問題中包含確切的類型,因爲它分散了其他方面,而這一部分我寧願管理自己。 – ideasman42

回答

5

在Rust中表示迭代的慣用方式是使用Iterator。因此,您將實現一個迭代器,該迭代器執行n = n.next,然後使用for循環遍歷迭代器。

struct MyIter<'a> { 
    pos: &'a MyData, 
    start: &'a MyData, 
} 
impl<'a> Iterator for MyIter<'a> { 
    type Item = &'a MyData; 
    fn next(&mut self) -> Option<&'a MyData> { 
     if self.pos as *const _ == self.start as *const _ { 
      None 
     } else { 
      let pos = self.pos; 
      self.pos = self.pos.next; 
      Some(pos) 
     } 
    } 
} 

爲讀者做練習,以適應這個迭代器能夠從第一要素,而不是從第二開始啓動它留下。

2

鏽病支持if模式匹配和while

  • 而不是具有一個布爾條件下,測試被認爲是成功的,如果所述模式匹配
  • 作爲圖案匹配的一部分,則結合相匹配的值名

因此,如果不是有一個布爾條件,你正在構建一個Option ...

fn check(next: *mut Node, init: *mut Node) -> Option<*mut Node>; 

let mut n = n_init; 
loop { 
    func(n); 
    if let Some(x) = check(n.next, n_init) { 
     n = x; 
    } else { 
     break; 
    } 
} 

但是,如果你可以使用Iterator,你會更習慣。

+0

雖然有趣的(在某些情況下可能是一個很好的解決方案),但它看起來像是一個循環的和間接的答案,這使得流量控制不太清晰,然後只要達到初始值就斷開。 – ideasman42

+0

@ ideasman42:完全同意,但如果你想在條件中賦值,這是我能想到的唯一模式(我不會鼓勵它的使用)。 –