2016-06-12 4 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 ожидает функцию без бокса, но я получаю ту же ошибку, если попытаюсь выполнить функцию boxed.

Обратите внимание, что в то время, когда этот вопрос был задан, 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>, потому что для того, чтобы вызвать его, вам необходимо пройти self по значению, а это значит, что вам нужно разыменовать Box, но это дает несортированный тип, не может быть передано по значению (с ржавчины 1.9).

Текущее обходное решение заключается в использовании неустойчивой черты FnBox вместо FnOnce. FnBox автоматически применяется для всех типов, которые реализуют FnOnce. Вот как мы можем использовать его:

#![feature(fnbox)] 

use std::boxed::FnBox; 

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

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

Обратите внимание, что вызов Command::spawn получает замыкание, которое вызывает FnBox, потому что мы не можем передать FnBox непосредственно Command::spawn по причинам, указанным выше. Кроме того, я должен был явно аннотировать тип аргумента при первом закрытии, иначе компилятор пожаловался (expected concrete lifetime, found bound lifetime parameter, который, я думаю, является ошибкой в ​​компиляторе).

+0

Спасибо. В основном это означает, что я буду иметь 2 распределения функций и 2 вызова функций правильно? Можно ли также расширить «Coroutine», чтобы он также мог принять «Box » вместо «FnOnce»? И тогда мне не пришлось бы делать обход с FnBox? –

+0

Да, будет 2 распределения функций, но замыкание, которое вызывает 'FnBox', выделяется в стеке, поэтому оно относительно дешево. Да, будет дополнительный вызов функции. Кроме того, «Coroutine» можно было бы адаптировать, хотя у вас есть «Box » и «Coroutine» в настоящее время имеет дело с «Box », которые несовместимы. –

Смежные вопросы