2015-01-26 7 views
9

Jak wklejasz funkcje (lub wskaźniki funkcji) do tablicy w celach testowych?Jak mogę przechowywać wskaźniki funkcji w tablicy?

fn foo() -> isize { 1 } 
fn bar() -> isize { 2 } 

fn main() { 
    let functions = vec![foo, bar]; 
    println!("foo() = {}, bar() = {}", functions[0](), functions[1]()); 
} 

Ten kod w Rust playground

Jest to kod błędu pojawia się:

error: mismatched types: 
expected `fn() -> isize {foo}`, 
    found `fn() -> isize {bar}` 
(expected fn item, 
    found a different fn item) [E0308] 

    let functions = vec![foo, bar]; 
           ^~~ 

Rust traktuje swoich funkcji (wartości), jak różne rodzaje mimo że te same podpisy, które ja znaleźć zaskakujące.

+0

Tak, to jest duplikatem. –

+0

Jeśli jest to duplikat, wskaż jego duplikat, abyśmy mogli nim zarządzać! To pytanie pomogło mi bardzo, w przeciwieństwie do innych (podobnych) pytań z błędnymi lub nieprzydatnymi, zaakceptowanymi odpowiedziami. –

Odpowiedz

10

W pewnym momencie każda funkcja otrzymała własny, odrębny typ z ... powodów, których nie pamiętam. Skutek jest taki, że trzeba dać kompilator wskazówkę (nota typ na functions):

fn foo() -> isize { 
    1 
} 
fn bar() -> isize { 
    2 
} 
fn main() { 
    let functions: Vec<fn() -> isize> = vec![foo, bar]; 
    println!("foo() = {}, bar() = {}", functions[0](), functions[1]()); 
} 

Można również zrobić to w taki sposób:

let functions = vec![foo as fn() -> isize, bar]; 
+0

Dzięki! Zawsze szkoda, że ​​przypadek użycia staje się trudniejszy; Mam nadzieję, że mieli jakiś powód tej przełomowej zmiany. Adnotowanie typu po lewej stronie nie jest takie złe - jeśli wiesz, jak pisać podpisy funkcji, których jeszcze nie znałem. –

+0

"Elementy fn" mają tę zaletę: omijają połączenia za pomocą wskaźnika funkcji, który jest połączeniem wirtualnym. LLVM może * devirtualizować * to wywołanie w przepustce optymalizacyjnej, ale wywołanie fn item i unboxed powinno być zawsze bezpośrednie, bez polegania na optymalizatorze, aby to naprawić. – bluss

+0

Możesz umieścić je w tablicy, ale musisz mieć nieco więcej rzutowania: 'let functions = [foo jako fn() -> isize, bar jako fn() -> isize];' lub nawet 'let functions: [fn() -> isize; 2] = [foo, bar]; '. Można również utworzyć funkcję 'let: & [fn() -> isize] = & [foo, bar];'. – Shepmaster

Powiązane problemy