2014-12-05 4 views
1

내부 역 참조 폐쇄를 실행 내가 기능을 한 다음을 반복하는 벡터를 받아 각 단계에서 각각을 실행하는 몇 가지 코드가 있습니다. 나는이 함수 호출이 첫 번째 블록 두번째 등이있는의 비동기 대신 수행 할 수 있도록 작업없이 ... for 루프로 작업을 통합 할녹 : 작업

let mut arr: Vec<|i32| -> i32> = Vec::new(); 
arr.push(function1); 
arr.push(function2); 

let ref num_in = os::args()[1]; 
let num_str = num_in.to_string(); 

let num = match from_str::<i32>(num_str.as_slice()) { 
    Some(x) => x, 
    None => panic!("Not a number"), 
}; 

for f in arr.iter_mut() { 
    spawn(proc(){ 
     println!("{}", (*f)(num.clone())); 
    }); 
}; 

을 시도, 단순히를하고있는 중이 야 println! for 루프 내에서이 코드는 잘 실행되지만 차단 방법으로 작업을 사용하여 피하려고합니다. 작업과 나는 이러한 오류 및 메모 ...

error: the trait 'core::kinds::Send' is not implemented for the type '&mut |i32| -> i32'

을 얻을

note: the closure that captures 'f' requires that all captured variables implement the trait 'core::kinds::Send'

답변

1

코드에서 문제의 몇 가지가 있습니다 : 컴파일러가 당신을 말하고있다처럼

f가있다가, a &mut |i32|->i32. 벡터 요소 중 하나에 대한 빌린 참조입니다. 이러한 빌린 참조는 작업 경계를 넘어 전송 될 수 없습니다. 스코프 기반 수명 보장은 여러 스레드가 관련되어있는 경우 간단히 작동하지 않기 때문에 포인터가 매달 리지 않도록 메모리 안전 오류를 방지하는 것은 쉬운 규칙입니다.

그러나 유형이 |i32|->i32 인 경우에도 현재 환경을 빌려 오기 때문에 일반적으로 빌린 참조와 비슷합니다. 변수를 포착하지 않으면 ("빈 환경"), 대신 fn(i32) -> i32을 사용하여 보낼 수있는 항목을 얻을 수 있습니다. 간단한 함수 포인터라고 생각할 수 있습니다.

분들께 다른 작업 (에서와 같이 "빌린 없습니다")의 자신의 환경을 전달 보통 proc 이루어집니다 뭔가를 실행합니다. 그것이 그 목적입니다. 그런 이유로 이미 proc을 (를) 사용하고 있습니다. 컴파일러는 procf을 복사하여 빌린 참조를 보낼 수 없으므로 전체 proc을 보낼 수 없습니다.

가까운 미래에 proc이 불필요하게되는 "박스 처리되지 않은 폐쇄"가 발생합니다. 그런 다음 Vec<proc(i32)->i32> 대신 Vec<Box<FnOnce(i32)->i32 + Send>> 또는 Vec<Box<Fn(i32)->i32 + Send>>을 사용할 수 있습니다. 그리고 이러한 종류의 상자를 만들려면 boxmove 키워드뿐만 아니라 특성 개체에 대한 캐스트가 필요합니다.

+0

첫 번째 줄을 'let mut arr : Vec i32> = Vec :: new();'으로 변경 했으므로 이제 오류가 발생합니다 : '오류 :'arr '이 충분하지 않습니다.' – AllTheTime

+0

@ AllTheTime : 완전한 예를 제공해주십시오. 언급하는 것을 잊어 버렸습니다. 벡터 반복자는 참조를 산출합니다. – sellibitze