2015-06-27 20 views
9

Uczę się teraz Rust i wydaje mi się, że nie mogę określić zamknięcia jako parametru funkcji. Oto co mam:Nie można przekazać zamknięcia jako parametru

fn foo(a: i32, f: |i32| -> i32) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, |x| { x + 1 }); 
    println!("{}", bar); 
} 

pojawia się następujący błąd:

foo.rs:1:19: 1:20 error: expected type, found `|` 
foo.rs:1 fn foo(a: i32, f: |i32| -> i32) -> i32 { 

Ok, więc to nie podoba składni zamknięcia. To jest trochę denerwujące, ponieważ teraz muszę to napisać:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, Box::new(|x| { x + 1 })); 
    println!("{}", bar); 
} 

Co się dzieje? Czytałem w kilku różnych places, że pierwszy przykład jest poprawny, podobnie jak usunięto składnię "typu zamknięcia", czy też robię coś nie tak?

Odpowiedz

6

Rdza została opracowana na otwartej przestrzeni od samego początku i od tego czasu język bardzo się rozwinął. Artykuł z przepełnieniem stosu, z którym się łączysz, ma prawie 1 rok, co w czasach przedrucznych jest tak długi jak całe życie ... (kalambur przeznaczony)

Najprostsza odpowiedź brzmi: należy pamiętać, że wiele artykułów, postów na blogach, odpowiedzi na SO ... nie są już istotne, ponieważ język się zmienił. Jeśli wypróbujesz rozwiązanie i nie zadziała, po prostu znajdź nowszą składnię (tak jak robiłeś to!) I przejdź dalej.

W tym konkretnym przypadku this RFC dokumentuje zmianę z |...| -> ... na Fn/FnMut/FnOnce(...) -> ....

Nawiasem mówiąc, istnieje plan wysiłku społeczności, aby znaleźć nieaktualne artykuły i wyraźnie oznaczyć je jako przestarzałe, aby uniknąć tego konkretnego problemu. Nie mogę jednak znaleźć linku do tego.

+1

[RFC 114] (https://github.com/rust-lang/rfcs/blob/master/text/0114-closures.md) jest bardziej odpowiedni dla tej zmiany niż RFC 231, ale szczegóły RFC 114 nie są aktualne (na przykład 'Fn' to teraz' FnMut', a 'FnShare' to teraz' Fn'). –

+0

* jawnie oznacz je jako przestarzałe * - lub po prostu poproś drugiego rozmówcę, aby zaktualizował odpowiedź^_ ^. Zrobiłem to i zostało zaktualizowane za kilka minut. Teraz, czy to pytanie powinno zostać oznaczone jako duplikat? – Shepmaster

+0

Nie miałem na myśli, ale raczej wpisów na blogu, gdzie treść nie jest aktualizowana przez społeczność. Może to być nawet niepożądane; na przykład posty na blogu Niko Matsakisa dotyczą raczej procesu myślowego - zachowałbyś go raczej jako odniesienie historyczne niż aktualny dokument. – mdup

4

Jeśli ktoś jest zainteresowany to pytanie dzisiaj, oto składnia z rodzajowych:

fn foo<F: Fn(i32) -> i32>(a: i32, f: F) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, |x| { x + 1 }); 
    println!("{}", bar); 
} 

Lub przy cechy obiektów:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, Box::new(|x| { x + 1 })); 
    println!("{}", bar); 
} 

Należy wolą tych pierwszych.

Powiązane problemy