Почему я не могу создать предопределенное замыкание в области поперечной балки

#multithreading #rust

#многопоточность #Ржавчина

Вопрос:

Почему это работает:

 extern crate crossbeam;
fn main(){
    let v: Vec<i32> = vec![1, 2, 3];

    crossbeam::scope(|s|{
        s.spawn(|_|{
            for e in v{
                println!("{}", e);
            }
        });
    }).unwrap();
}
  

когда это не:

 extern crate crossbeam;
fn main(){
    let v: Vec<i32> = vec![1, 2, 3];
    let closure = |_|{
        for e in v{
            println!("{}", e);
        }
    };

    crossbeam::scope(|s|{
        s.spawn(closure);
    }).unwrap();
}
  

компилятор выдает мне ошибку:

 error[E0308]: mismatched types
  --> src/main.rs:11:11
   |
11 |         s.spawn(closure);
   |           ^^^^^ one type is more general than the other
   |
   = note: expected type `std::ops::FnOnce<(amp;crossbeam::thread::Scope<'_>,)>`
              found type `std::ops::FnOnce<(amp;crossbeam::thread::Scope<'_>,)>`
  

Это из-за более высоких границ признака ранга?

И если да, то как я могу это исправить, сохраняя определение замыкания за пределами области?

Я новичок в rust, и я обнаружил, что ошибка сбивает с толку, потому что тип, который она обнаружила, соответствует типу, который она ожидала, насколько я могу судить.

Ответ №1:

Проблема в том, что rust не может правильно определить тип замыкания (не вдаваясь в подробности, скажем, что компилятор не слишком хорош в определении типа между замыканиями).

В вашем случае вам просто нужно было добавить указание типа для всех аргументов замыкания, например

 extern crate crossbeam;
fn main(){
    let v: Vec<i32> = vec![1, 2, 3];
    let closure =  |sr:amp; crossbeam::thread::Scope<'_> /* anotate the closure arguments types */|{
        for e in v{
            println!("{}", e);
        }
    };

    crossbeam::scope(|s|{
        s.spawn(closure);
    }).unwrap();
}
  

Обратите внимание, что ваша проблема похожа на эту.

Комментарии:

1. Спасибо, я предполагаю, что я немного подтолкнул компилятор, пытаясь заставить его сделать вывод за меня.