Rust中的函式指標

Pomelo_劉金發表於2023-05-03

什麼是函式指標

透過函式指標允許我們使用函式作為另一個函式的引數。函式的型別是 fn (使用小寫的 ”f” )以免與 Fn 閉包 trait 相混淆。fn 被稱為 函式指標(function pointer)。指定引數為函式指標的語法類似於閉包。

函式指標型別(使用關鍵字 fn 寫出)指向那些在編譯時不必知道函式識別符號的函式。它們也可以由函式項型別或非捕獲(non-capturing)閉包經過一次自動強轉(coercion)來建立

如何在Rust中定義和使用函式指標

下面是一個簡單的程式碼示例,它演示瞭如何在Rust中定義和使用函式指標:

fn add_one(x: i32) -> i32 {
x + 1 
} 
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
f(arg) + f(arg) 
} 
fn main() { 
let answer = do_twice(add_one, 5);
println!("The answer is: {}", answer); 
}
複製程式碼

這會列印出 The answer is: 12。do_twice 中的 f 被指定為一個接受一個 i32 引數並返回 i32 的 fn。接著就 可以在 do_twice 函式體中呼叫 f。在 main 中,可以將函式名 add_one 作為第一個引數傳遞給 do_twice。

函式指標與閉包的區別

函式指標和閉包都可以用來表示可呼叫物件,但它們之間有一些重要的區別。其中一個區別是,閉包可以捕獲其周圍環境中的變數,而函式指標則不能。

不同於閉包,fn 是一個型別而不是一個 trait,所以直接指定 fn 作為引數而不是宣告一個帶有 Fn 作為 trait bound 的泛型引數。

函式指標實現了所有三個閉包 trait(Fn、FnMut 和 FnOnce),所以總是可以在呼叫期望閉包的函式時 傳遞函式指標作為引數。

傾向於編寫使用泛型和閉包 trait 的函式,這樣它就能接受函式或閉包作為引數。 一個只期望接受 fn 而不接受閉包的情況的例子是與不存在閉包的外部程式碼互動時:C 語言的函式可以接受函式作為引數,但 C 語言沒有閉包。

函式指標的應用場景

  • 可以作為引數傳遞給其他函式,以便在函式內部呼叫。這在一些高階函式(higher-order functions)中非常常見,例如 map 和 filter 等。

  • 函式指標還可以用於定義回撥函式(callback functions),例如在事件驅動程式設計(event-driven programming)中。

  • 函式指標還可以儲存在資料結構中,以便稍後呼叫。這在一些演演算法中非常有用,例如排序演演算法。

函式指標的優缺點

函式指標的優點之一是它們沒有執行時開銷。這意味著它們可以在不影響效能的情況下用於表示可呼叫物件。

但是,函式指標也有一些侷限性。例如,它們不能捕獲其周圍環境中的變數,這使得它們不如閉包靈活。此外,函式指標只能指向那些在編譯時已知的函式,這意味著它們不能用於表示匿名函式。from劉金,轉載請註明原文連結。感謝!

 

相關文章