2014-11-22 3 views
9

에 인수로 함수를 전달하는 :방법은 다음과 녹 프로그램을 감안할 때 녹

fn call_twice<A>(val: A, f: fn(A) -> A) -> A { 
    f(f(val)) 
} 

fn main() { 
    fn double(x: int) -> int {x + x}; 
    println!("Res is {}", call_twice(10i, double)); 
    // println!("Res is {}", call_twice(10i, (x: int) -> int {x + x})); 
    //^this line will fail 
} 

왜 내가 함수와 double 통과 할 수 있지만, 인라인하지? 어딘가에 함수를 정의하지 않고 동일한 동작을 달성하는 좋은 방법은 무엇입니까?

답변

13

2016년 4월 1일 업데이트 :

녹 1.0로, 코드는 다음과 같아야합니다

폐쇄 지금 언 박싱이기 때문에
fn call_twice<A, F>(val: A, mut f: F) -> A 
where F: FnMut(A) -> A { 
    let tmp = f(val); 
    f(tmp) 
} 

fn main() { 
    fn double(x: i32) -> i32 {x + x}; 
    println!("Res is {}", call_twice(10, double)); 
    println!("Res is {}", call_twice(10, |x| x + x)); 
} 

폐쇄 매개 변수에 대한 변경은 . 원래

: 내가 아는 한

하는 한, 당신은 인라인 그런 기능을 정의 할 수 없습니다.

당신이 무엇입니까 을 원하시는 분은입니다. 다음 작품 :

  1. 기능이 폐쇄를 강요하지만, 그 반대는 사실이 아니다 :

    fn call_twice<A>(val: A, f: |A| -> A) -> A { 
        let tmp = f(val); 
        f(tmp) 
    } 
    
    fn main() { 
        fn double(x: int) -> int {x + x}; 
        println!("Res is {}", call_twice(10i, double)); 
        println!("Res is {}", call_twice(10i, |x| x + x)); 
    } 
    

    주의해야 할 몇 가지가 있습니다.

  2. 차용 규칙으로 인해 f(val)의 결과를 임시로 저장해야합니다. 짧은 버전 : 폐쇄 호출에 고유 한 액세스가 필요하며 차용 검사기가 두 호출이 원래 위치에서 독립적이라는 것을 인식 할만큼 충분히 똑똑하지 않습니다.

  3. 클로저는 박스 처리되지 않은 폐쇄으로 대체되는 중이므로 나중에 변경 될 예정이지만 아직 아직 완료되지 않았습니다.

+0

설명해 주셔서 감사합니다. 임시 변수에 약간 이상하지만, 좀 더 안정적인 버전으로 수정 될 것입니다. –

+0

이것은 녹 1.7에서 작동하지 않는 것 같습니다. https://play.rust-lang.org/?gist=ad35b80eeae1d1966944a66a75d0ad80&version=stable –

+2

@SandeepDatta이 답변은 2014 년부터 제공됩니다; 이 코드는 녹 1.0에서도 유효하지 않았을 것입니다. 나는 그것을 업데이트했다. –