2016-06-12 68 views
4

Coroutine-rs約束的特點是不滿足

這是我想調用的函數:

#[inline] 
pub fn spawn<F>(f: F) -> Handle 
    where F: FnOnce(&mut Coroutine) + Send + 'static 
{ 
    Self::spawn_opts_impl(Box::new(f), Options::default()) 
} 

然後我創建了一個枚舉,因爲其實我是想從一個線程發送到另一個,這這也是我爲什麼裝盒的原因。我也符合特質限制。

enum Message { 
    Task(Box<FnOnce(&mut Coroutine) + Send + 'static>), 
} 

但是,如果我嘗試提取從Message功能:

fn main(){ 
    let m = Message::Task(Box::new(|me| { 
    })); 
    let c = match m{ 
     Message::Task(f) => Coroutine::spawn(f) 
    }; 
} 

我收到以下錯誤:

src/main.rs:168:29: 168:45 error: the trait bound `for<'r> Box<for<'r> std::ops::FnOnce(&'r mut coroutine::asymmetric::Coroutine) + Send>: std::ops::FnOnce<(&'r mut coroutine::asymmetric::Coroutine,)>` is not satisfied [E0277] 
src/main.rs:168   Message::Task(f) => Coroutine::spawn(f) 
              ^~~~~~~~~~~~~~~~ 
src/main.rs:168:29: 168:45 help: run `rustc --explain E0277` to see a detailed explanation 
src/main.rs:168:29: 168:45 help: the following implementations were found: 
src/main.rs:168:29: 168:45 help: <Box<std::boxed::FnBox<A, Output=R> + 'a> as std::ops::FnOnce<A>> 
src/main.rs:168:29: 168:45 help: <Box<std::boxed::FnBox<A, Output=R> + Send + 'a> as std::ops::FnOnce<A>> 
src/main.rs:168:29: 168:45 note: required by `coroutine::asymmetric::Coroutine::spawn` 

我不知道是什麼鏽病是想告訴我這裏。我假設問題是spawn需要一個非盒裝函數,但如果我嘗試去裝入盒裝函數,我會得到相同的錯誤。

請注意,在這個問題被問及時,coroutine-rs不會生成,我修復了錯誤this fork

回答

4

讓我們仔細閱讀錯誤消息:

src/main.rs:168:29: 168:45 error: the trait bound 
    `for<'r> 
     Box< 
      for<'r> std::ops::FnOnce(
       &'r mut coroutine::asymmetric::Coroutine 
      ) + Send 
     >: 
    std::ops::FnOnce< 
     (
      &'r mut coroutine::asymmetric::Coroutine, 
     )>` is not satisfied [E0277] 

基本上,你想一個Box<FnOnce>傳遞給希望實現FnOnce一個類型的函數。

但是,你不能調用一個函數,在Box<FnOnce>,因爲爲了調用它,你需要的值,這意味着你需要取消引用Box通過self,但產生的無膠型,其不能通過價值傳遞(截至Rust 1.9)。

當前的解決方法是使用不穩定的FnBox特徵而不是FnOnce。對於實施FnOnce的所有類型,將自動執行FnBox。下面是我們如何使用它:

​​

注意,調用Command::spawn接收調用FnBox,因爲我們無法通過FnBox直接Command::spawn上面提到的原因關閉。另外,我必須在第一次關閉時顯式註釋參數類型,否則編譯器會抱怨(expected concrete lifetime, found bound lifetime parameter,我認爲這是編譯器中的一個錯誤)。

+0

謝謝。基本上這意味着我將有2個函數分配和2個函數調用嗎?是否也可以擴展'協同程序',以便它也可以接受'Box '而不是'FnOnce'?然後我就不必繞着FnBox繞道了? –

+0

是的,會有2個函數分配,但調用'FnBox'的閉包被分配到棧上,所以它相對便宜。是的,會有一個額外的函數調用。此外,'協程'可能可以改編,雖然你有一個'Box '和'協同程序'目前處理'盒子',它們是不兼容的。 –