2016-03-06 40 views
10

我試圖實現一個返回遞歸閉包的函數,雖然我不知道如何在函數簽名中表示該函數。這裏是Python中的工作實現的示例代碼返回遞歸閉包的函數簽名

def counter(state): 
    def handler(msg): 
     if msg == 'inc': 
      print state 
      return counter(state + 1) 

     if msg == 'dec': 
      print state 
      return counter(state - 1) 
    return handler 

c = counter(1) 
for x in range(1000000): 
    c = c('inc') 

和Rust的僞代碼。

enum Msg { 
    Inc, 
    Dec 
} 

fn counter(state: Int) -> ? { 
    move |msg| match msg { 
     Msg::Inc => counter(state + 1), 
     Msg::Dec => counter(state - 1), 
    } 
} 

回答

11

由於鏽支持遞歸類型,你只需要遞歸編碼在獨立的結構:

enum Msg { 
    Inc, 
    Dec, 
} 

// in this particular example Fn(Msg) -> F should work as well 
struct F(Box<FnMut(Msg) -> F>); 

fn counter(state: i32) -> F { 
    F(Box::new(move |msg| match msg { 
     Msg::Inc => { 
      println!("{}", state); 
      counter(state + 1) 
     } 
     Msg::Dec => { 
      println!("{}", state); 
      counter(state - 1) 
     } 
    })) 
} 

fn main() { 
    let mut c = counter(1); 
    for _ in 0..1000 { 
     c = c.0(Msg::Inc); 
    } 
} 

我們不能用拳擊做離開了這裏,遺憾的是 - 因爲未裝箱封有難以名狀的類型,我們需要將它們放入特徵對象中,以便能夠在結構聲明中命名它們。