2015-02-08 112 views
2

我想實現一個JavaScript風格的回調。我有一個使用庫的應用程序(都是我的),我需要應用程序能夠將一個閉包或函數傳遞給庫中的一個方法,然後在線程中產生一個線程並在線程內部滿足條件呼叫回撥。如何實現JavaScript風格的回調?

main.rs

fn main(){ 
    welcome_message(); 
    mylib::connect(|| println!("Connected to service! Please enter a command. (hint: help)\n\n")); 
    loop { 
     match prompt_input() { 
      true => {}, 
      false => break, 
     } 
    } 
} 

lib.rs

pub fn connect<F>(resolve: F) -> (mpsc::Sender<Message>, mpsc::Receiver<Message>) 
    where F: Fn() 
{ 

    ... 

    let receive_loop = Thread::scoped(move || { 
     for response in receiver.incoming_messages::<Message>(){ 
      let json_string = match response.unwrap() { 
       Message::Text(txt) => txt, 
       _ => "".to_string(), 
      }; 
      let message = json::Json::from_str(json_string.as_slice()); 
      let message_json = message.unwrap(); 
      if message_json.is_object() { 
       let ref something = receiver_tx; 
       let obj = message_json.as_object().unwrap(); 
       let something_json = obj.get("lsri").unwrap(); 
       let something = something_json.to_string().replace("\"", ""); 
       match something.as_slice() { 
        "service#connected" => resolve(), 
        _ => println!("{}", type), 
       } 
      } else { 
       println!("Invalid service response"); 
      } 
     } 
    }); 

    ... 

} 

錯誤

src/lib.rs:54:24: 54:38 error: the trait `core::marker::Send` is not implemented for the type `F` [E0277] 
src/lib.rs:54  let receive_loop = Thread::scoped(move || { 
            ^~~~~~~~~~~~~~ 
src/lib.rs:54:24: 54:38 note: `F` cannot be sent between threads safely 
src/lib.rs:54  let receive_loop = Thread::scoped(move || { 
            ^~~~~~~~~~~~~~ 

它並不需要是一個封閉,我傳球,我可以通過一個函數太。它不需要任何參數或返回類型,但如果有幫助,我可以添加一些虛擬參數。我非常樂於提供其他方法或途徑來達到同一目標的建議。

我已經嘗試使用:

  • 主題::產卵
  • FnMut()
  • 弧::新(解析)(與實施.clone的())
  • 弧:: new(Mutex :: new(resolve))(執行.lock())
  • 在Google上搜索示例
  • 讀取Rust書的全部內容
  • 搜索例子
  • 所有上述的各種配置
  • 錯誤消息

這是可能的鏽?有沒有更好的辦法?

非常感謝您提前預約。

解決方案:

對於任何人在將來找到這個,每低於我的回答的指示改變connect簽名的下面,這使得回調被傳遞到線程。

pub fn connect<'a, T, F>(resolve: F) -> (mpsc::Sender<Message>, mpsc::Receiver<Message>) 
    where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a 
+0

請注意,Rust風格是4空間縮進。 – Shepmaster 2015-02-08 04:48:12

+0

啊,我可以解決,如果你願意,這是在我的代碼,但爲了可讀性和間距的問題,我把它減少到兩個 – SnareChops 2015-02-08 04:49:06

+0

如果你能產生一個[MCVE](http://堆棧溢出。com/help/mcve),特別是在[Playpen](https://play.rust-lang.org/)中編譯(或者有適當的錯誤)。現在,您的代碼使用'type'作爲變量名稱,這是無效的Rust。 – Shepmaster 2015-02-08 04:50:07

回答

2

嘗試標誌着你的F有相同的限制Thread::scoped

fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> 
    where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a 

具體而言,與Send特徵邊界的類型應該明確的

性狀core::marker::Send是即時錯誤未實施類型F

+0

這解決了這個問題,並且非常有幫助。謝謝。現在到下一個與這個問題密切相關的問題,但應該是一個快速的答案。我應該在SO上創建一個新問題,還是將其添加爲我的文章的編輯?它與'match'塊中的回調調用有關。 – SnareChops 2015-02-08 05:21:05