2014-11-01 2 views
0

컨텍스트 : 다른 함수로 함수를 매개 변수화하려고 시도하고 정적으로 해결하려고합니다. 한눈에 Fn 특성 경계가 내 필요와 일치하는 것 같습니다. 나는했습니다UFCS : T :: 메서드 해결

fn binop<T,Op:Fn<(T,T),T>>(op: Op, a:T, b:T) -> T { 
    // [...] 
    op.call((a,b)) 
} 

fn addx(a: f64, b: f64) -> f64 { 
    binop(f64::add, a, b) 
    // ^~~~~~~~ error: unresolved name `f64::add`. 
} 

fn main() { 
    addx(1.0, 2.0); 
} 

: 나는 "래퍼"가 될 것으로 예상 무엇

잘 보인다 (지금까지), I는 그러나 심하게 단지 지정 방식에 갇혀있어 내가 전달하고 싶습니다 UFCS RFC에서 힌트를 찾고 "무작위로"지정 변종 (최대 std::ops::Add::add을 참조하고 작업을 수행하는 일부 마법 추론에 호핑)까지 시도했지만 옳았습니다. 해상도 메커니즘에 대한 모든 도움 (/ 포인터)을 많이 주시면 감사하겠습니다.

감사!

답변

1

Fn 새로운 박스 없음 폐쇄 물건입니다 (그것을 here를보십시오). 간단한 함수 유형 인 바로 fn(…) -> …도 있습니다. rustc 통해

fn binop<T>(op: fn(&T, &T) -> T, a: &T, b: &T) -> T { 
    // [...] 
    op(a, b) 
} 

fn addx(a: f64, b: f64) -> f64 { 
    binop(Add::add, &a, &b) 
} 

fn main() { 
    addx(1.0, 2.0); 
} 

실행이 당신이 얻을 : 이런 종류의 (마음에 베어링이 add은 값이 아닌 참조로 인수를 소요)

error: internal compiler error: unexpected failure 
note: the compiler hit an unexpected failure path. this is a bug. 
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html 
note: run with `RUST_BACKTRACE=1` for a backtrace 
task 'rustc' failed at 'assertion failed: `(left == right) && (right == left)` (left: `3`, right: `0`)', /home/chris/rust/src/librustc/middle/trans/callee.rs:528 

... 흠, 아마 정도 이 특별한 경우에 좋습니다. 그것은 형질 추론과 관련이 있을지 모르지만 무엇을 말할 수는 없습니다.

+0

ICE에서 비슷한 문제가 있다고보고했습니다. https://github.com/rust-lang/rust/issues/18501 – pao

+0

[# 18061] (https://github.com/rust-lang/rust/)에서 수정되었습니다. issues/18061), 당신의 예제는 이제 작동합니다. 감사. – pao

1

Fn* 특징은 클로저 특성을 unboxed하고 unboxed closure는 현재 개발 중입니다. 함수에서 인스턴스로의 자동 변환과 같은 일부 편의는 아직 작동하지 않습니다.하지만 박스 처리되지 않은 클로저가 현재 박스형 패키지를 대체 할 것으로 믿고 있지만, 이와 같은 기능은 향후에 작동합니다.

그러나 다른 문제가 있습니다. UFCS is not implemented 아직, 그리고 그들은 1.0에 대해 구현되지 않을 것입니다, 그래서 당신은 일반적으로 특성 메서드를 지정할 수 없습니다. 당신은 예를 들어, 명시 적 폐쇄 구조를 사용해야합니다 :

#![feature(unboxed_closures, unboxed_closure_sugar, overloaded_calls)] 

fn binop<T, Op: Fn(T, T) -> T>(op: Op, a: T, b: T) -> T { 
    // [...] 
    op(a, b) 
} 

fn addx(a: f64, b: f64) -> f64 { 
    binop(|&: a: f64, b: f64| a + b, a, b) 
} 

fn main() { 
    println!("{}", addx(1.0, 2.0)); 
} 

+0

감사합니다. 몇 가지 커밋이 시작되었지만 전체적으로 RFC가 실제로 완료되지 않았기 때문에 나는 동행하는 github 문제를 면밀히 살펴 봐야했습니다. 죄송합니다. – pao

관련 문제