共用方式為


內嵌函式

內嵌函式 是直接整合到呼叫程式代碼中的函式。

使用內嵌函式

當您使用靜態類型參數時,類型參數所參數化的任何函式都必須內嵌。 這可確保編譯程式可以解析這些類型參數。 當您使用一般泛型類型參數時,沒有任何這類限制。

除了啟用成員條件約束的使用之外,內嵌函式對於優化程式代碼很有説明。 不過,過度使用內嵌函式可能會導致程式代碼對編譯程式優化和連結庫函式實作的變更較不具抗拒性。 基於這個理由,除非您已嘗試所有其他優化技術,否則您應該避免使用內嵌函式進行優化。 讓函式或方法內嵌有時可以改善效能,但情況不一定如此。 因此,您也應該使用效能測量來確認讓任何指定的函式內嵌實際上都有正面效果。

inline修飾詞可以套用至最上層、模組層級或類別中方法層級的函式。

下列程式代碼範例說明最上層的內嵌函式、內嵌實例方法和內嵌靜態方法。

let inline increment x = x + 1
type WrapInt32() =
    member inline this.incrementByOne(x) = x + 1
    static member inline Increment(x) = x + 1

內嵌函式和類型推斷

的存在 inline 會影響類型推斷。 這是因為內嵌函式可以具有靜態解析的類型參數,而非內嵌函式則不能。 下列程式代碼範例示範的案例 inline 很有用,因為您使用的是具有靜態解析類型參數的函式, float 也就是轉換運算符。

let inline printAsFloatingPoint number =
    printfn "%f" (float number)

inline如果沒有修飾詞,類型推斷會強制函式採用特定類型,在此情況下int為 。 但是使用 inline 修飾詞時,函式也會推斷為具有靜態解析的類型參數。 inline使用 修飾詞時,類型會推斷為下列專案:

^a -> unit when ^a : (static member op_Explicit : ^a -> float)

這表示函式接受支援轉換為 float 的任何類型。

InlineIfLambda

F# 編譯程式包含執行內嵌程式代碼的優化器。 屬性 InlineIfLambda 可讓程式代碼選擇性地指出,如果自變數判斷為 Lambda 函式,則該自變數應該一律內嵌在呼叫月臺。 如需詳細資訊,請參閱 F# RFC FS-1098

例如,請考慮下列 iterateTwice 函式來周遊數位列:

let inline iterateTwice ([<InlineIfLambda>] action) (array: 'T[]) =
    for i = 0 to array.Length-1 do
        action array[i]
    for i = 0 to array.Length-1 do
        action array[i]

如果通話網站為:

let arr = [| 1.. 100 |]
let mutable sum = 0
arr  |> iterateTwice (fun x ->
    sum <- sum + x)

然後在內嵌和其他優化之後,程式代碼會變成:

let arr = [| 1..100 |]
let mutable sum = 0
for i = 0 to arr.Length - 1 do
    sum <- sum + arr[i] 
for i = 0 to arr.Length - 1 do
    sum <- sum + arr[i] 

不論涉及 Lambda 表達式的大小為何,都會套用此優化。 這項功能也可以用來實作迴圈取消卷動,並更可靠地實作類似的轉換。

可以加入警告 (/warnon:3517 或 屬性 <WarnOn>3517</WarnOn>) 可以開啟,以指出程式代碼 InlineIfLambda 中自變數未繫結至呼叫月臺的 Lambda 運算式的位置。 在正常情況下,不應啟用此警告。 不過,在某些類型的高效能程序設計中,確保所有程式代碼都內嵌和扁平化會很有用。

另請參閱