共用方式為


使用 F 進行互動式程式設計#

F# Interactive (dotnet fsi) 可用來在控制台以互動方式執行 F# 程式代碼,或執行 F# 腳本。 換句話說,F# 互動式會執行 F# 的 REPL(讀取、評估、列印迴圈)。

若要從主控台執行 F# Interactive 請執行 dotnet fsi。 您可以在任何 .NET SDK 中找到 dotnet fsi

備註

如果您打算在 .NET Framework 執行環境下使用 F# 互動式,您需要安裝 Visual Studio Build Tools 或 Visual Studio 的一個版本,並從“開發人員命令提示字元”中執行 FsiAnyCPU.exe 命令,或者直接將 FsiAnyCPU.exe 在環境變數 PATH 中設置可用,以替代 dotnet fsi 命令行。

工具支援定義 F# 互動式執行環境的版本:

  • 在 Visual Studio 中:在功能表欄中,[工具 / ] 和 [F# 工具 / F# 互動式],然後調整 [使用 .NET Core 腳本]。
  • 在 Visual Studio Code(ionide 擴充功能):在命令選擇區中,喜好設定:開啟使用者設定,然後 擴充功能 / F# / FSharp:Fsi Sdk 檔案路徑

如需可用命令行選項的詳細資訊,請參閱 F# 互動式選項

直接在 F# Interactive 中執行程式代碼

因為 F# Interactive 是 REPL (read-eval-print 循環),所以您可以在其中以互動方式執行程序代碼。 以下是從命令行執行 dotnet fsi 之後的互動式會話範例:

Microsoft (R) F# Interactive version 11.0.0.0 for F# 5.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> let square x = x *  x;;
val square : x:int -> int

> square 12;;
val it : int = 144

> printfn "Hello, FSI!"
- ;;
Hello, FSI!
val it : unit = ()

您會注意到兩個主要事項:

  1. 所有程式代碼都必須以雙分號終止 ,;;才能評估
  2. 程式碼被評估後儲存在 it 值中。 您可以以互動方式參考 it

F# Interactive 也支援多行輸入。 您只需要以雙分號 (;;) 終止提交。 請考慮下列程式碼片段,這段程式碼片段已經被貼入 F# Interactive 並加以評估:

> let getOddSquares xs =
-     xs
-     |> List.filter (fun x -> x % 2 <> 0)
-     |> List.map (fun x -> x * x)
-
- printfn "%A" (getOddSquares [1..10]);;
[1; 9; 25; 49; 81]
val getOddSquares : xs:int list -> int list
val it : unit = ()

>

會保留程式代碼的格式設定,而且有一個雙分號 (;;) 會終止輸入。 F# Interactive 接著會評估程式代碼並列印結果!

使用 F 編寫文稿#

在 F# Interactive 中以互動方式評估程式代碼可能是絕佳的學習工具,但您很快就會發現它不像在一般編輯器中撰寫程式代碼那麼具生產力。 若要支援一般程式代碼編輯,您可以撰寫 F# 文稿。

腳本會使用擴展名 .fsx。 您可以只執行 dotnet fsi 並指定腳本的檔名,而 F# Interactive 會讀取程式碼並即時執行,而不是編譯原始程式碼,然後稍後再執行已編譯的元件。 例如,請考慮下列名為 Script.fsx的腳本:

let getOddSquares xs =
    xs
    |> List.filter (fun x -> x % 2 <> 0)
    |> List.map (fun x -> x * x)

printfn "%A" (getOddSquares [1..10])

當您的機器中建立此檔案時,您可以使用 dotnet fsi 來執行它,然後直接在終端機視窗中查看輸出。

dotnet fsi Script.fsx
[1; 9; 25; 49; 81]

使用 Shebang 執行腳本

若要使 F# 腳本可執行而不需要明確調用 dotnet fsi,您可以在腳本的開頭使用 Shebang 行。 這可讓您直接從終端機執行腳本,例如 Shell 腳本。

例如,使用下列內容建立名為 ExecutableScript.fsx 的腳本檔案:

#!/usr/bin/env -S dotnet fsi

let getOddSquares xs =
    xs
    |> List.filter (fun x -> x % 2 <> 0)
    |> List.map (fun x -> x * x)

printfn "%A" (getOddSquares [1..10])
  1. 將腳本設為可執行檔:chmod使用 命令讓文稿成為可執行檔案:

    chmod +x ExecutableScript.fsx
    
  2. 直接執行腳本: 現在,您可以直接從終端機執行腳本:

    ./ExecutableScript.fsx
    

注意:Shebang 功能 (#!) 專屬於類似 Unix 的系統,例如 Linux 和 MacOS。 在 Windows 上,您可以使用 dotnet fsi Script.fsx 直接在終端機或命令提示字元中執行腳本。

此功能可在Linux和macOS等環境中使用F# 腳本時,提供更順暢的體驗。

Visual StudioVisual Studio Code 原生支援 F# 腳本。

在 F# Interactive 中參考套件

備註

套件管理系統是可延伸的,請參閱外掛程式 和擴充機制的詳細資訊。

自語言 5.0 版以來,F# Interactive 支援透過擴充性機制來參考套件;現用完后,即可使用 #r "nuget:" 語法和選擇性版本來參考 NuGet 套件:

#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json

let data = {| Name = "Don Syme"; Occupation = "F# Creator" |}
JsonConvert.SerializeObject(data)

如果未指定版本,則會採用最高可用的非預覽套件。 若要參考特定版本,請透過逗號引進版本。 當參考套件的預覽版本時,這很有用。 例如,使用 DiffSharp 的預覽版本來考慮此腳本:

#r "nuget: DiffSharp-lite, 1.0.0-preview-328097867"
open DiffSharp

// A 1D tensor
let t1 = dsharp.tensor [ 0.0 .. 0.2 .. 1.0 ]

// A 2x2 tensor
let t2 = dsharp.tensor [ [ 0; 1 ]; [ 2; 2 ] ]

// Define a scalar-to-scalar function
let f (x: Tensor) = sin (sqrt x)

printfn $"{f (dsharp.tensor 1.2)}"

根據預設, #r "nuget: ...." 不會使用還原期間所參考套件的組建目標。 此選項 usepackagetargets 可在需要時使用這些建置目標。 只有在套件設定在還原過程中需要它時,才新增 usepackagetargets=true 。 範例:

// load fsharp.data nugetpackage and consume buildtargets from fsharp.data package during restore.
#r "nuget:fsharp.data,usepackagetargets=true"
#r "nuget:fsharp.data,6.6.0,usepackagetargets=false"
#r "nuget:fsharp.data,6.6.0,usepackagetargets=true"

指定套件來源

您也可以使用 #i 命令來指定套件來源。 下列範例會指定遠端和本機來源:

#i "nuget: https://my-remote-package-source/index.json"
#i """nuget: C:\path\to\my\local\source"""
#i "nuget: /Users/username/path/to/my/local/source"
#i "nuget: /home/username/path/to/my/local/source"

指示解析引擎考慮新增至指令碼的遠端和/或本機來源。

您可以在指令碼中指定任意數量的套件來源。

這很重要

目前,相對路徑不支援使用 #i 指令。 您必須使用絕對路徑來指定本機套件來源。 此限制會在 dotnet/fsharp#12969 中追蹤。

因應措施:您可以使用 和 __SOURCE_DIRECTORY__以程式設計方式建構絕對路徑System.IO.Path.Combine(),然後使用字串插補將其傳遞給#i指令。 例如:

let localSource = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "relative/path/to/my/local/source")
#i $"""nuget: {localSource}"""

備註

目前使用架構參考的腳本有一項限制(例如Microsoft.NET.Sdk.WebMicrosoft.NET.Sdk.WindowsDesktop)。 無法使用土星、長頸鹿、WinForms 等套件。 此問題正追蹤於問題 #9417。 WinForms 仍適用於 F# Interactive 的 .NET Framework 版本。

若要載入 SDK 和/或工具隨附的其他擴充功能,請使用 --compilertool:<extensionsfolderpath> 旗標作為 F# 互動式會話的自變數(或在工具設定中)。

使用 F# 互動式參考磁碟上的元件

或者,如果您有磁碟上的元件,而且想要在腳本中參考該元件,您可以使用 #r 語法來指定元件。 請考慮編譯成 MyAssembly.dll的專案中的下列程式代碼:

// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y

編譯之後,您可以在名為 Script.fsx 的檔案中參考它,如下所示:

#r "path/to/MyAssembly.dll"

printfn $"{MyAssembly.myFunction 10 40}"

輸出如下所示:

dotnet fsi Script.fsx
90

您可以在腳本中指定任意多的程序集參考。

載入其他腳本

編寫腳本時,為不同工作選擇不同的腳本通常很有幫助。 有時候,您可能想要在另一個腳本中重複使用程式代碼。 您不必複製其內容到檔案中,而是只需使用 #load來載入和評估它。

請考慮下列事項 Script1.fsx

let square x = x * x

而取用的檔案: Script2.fsx

#load "Script1.fsx"
open Script1

printfn $"%d{square 12}"

您可以評估 Script2.fsx 如下:

dotnet fsi Script2.fsx
144

您可以在文稿中指定盡可能多的 #load 指示詞。

備註

需要 open Script1 宣告。 這是因為 F# 文稿中的建構會編譯成最上層模組,也就是其所輸入腳本檔案的名稱。 如果文稿檔案有小寫名稱,例如 script3.fsx ,則隱含模組名稱會自動大寫,而您必須使用 open Script3。 如果您想要在模組的特定命名空間中定義可載入文稿的建構,您可以包含模組宣告的命名空間,例如:

module MyScriptLibrary

在 F# 代碼中使用fsi物件

F# 文稿可以存取代表 F# 互動式工作階段的自訂 fsi 物件。 它可以讓您自訂例如輸出格式設定這類的功能。 這也是您可以存取命令行自變數的方式。

下列範例示範如何取得和使用命令行自變數:

let args = fsi.CommandLineArgs

for arg in args do
    printfn $"{arg}"

評估時,它會印出所有參數。 第一個自變數一律是評估的腳本名稱:

dotnet fsi Script1.fsx hello world from fsi
Script1.fsx
hello
world
from
fsi

您也可以使用 System.Environment.GetCommandLineArgs() 來存取相同的自變數。

F# 互動式指令參考

先前看到的#r#load 指示詞僅適用於 F# Interactive。 F# Interactive 中只有數個指示詞可用:

指令 說明
#r "nuget:..." 引用 NuGet 套件
#r "extname:..." 參考延伸模組的 extname 套件[^1] (例如 paket
#r "assembly-name.dll" 指向磁碟上的一個程序集
#load "file-name.fsx" 讀取來源檔案、編譯並執行它。
#help 顯示可用指令或特定功能文件的相關資訊。
#I 以引號指定元件搜尋路徑。
#quit 終止 F# 互動式工作階段。
#time on#time off #time 本身切換是否顯示效能資訊。 當它是 on時,F# Interactive 會針對解譯和執行的程式代碼的每個區段測量即時、CPU 時間和垃圾收集資訊。

[^1]:F # 互動式延伸模組的詳細資訊。

當您在 F# Interactive 中指定檔案或路徑時,應該使用字串常值。 因此,檔案和路徑必須加上引號,並且適用一般的跳脫字元。 您可以使用 @ 字元讓 F# Interactive 將包含路徑的字串解譯為逐字字串。 這會導致 F# Interactive 忽略任何跳脫字元。

在其他情況下,引號是選擇性的,從 F# 9 開始。

擴充 #help 指令

#help 指令現在支持顯示特定函式的文件。 您可以直接傳遞函式的名稱來擷取詳細數據。

#help List.map;;

輸出如下所示:

Description:
Builds a new collection whose elements are the results of applying the given function
to each of the elements of the collection.

Parameters:
- mapping: The function to transform elements from the input list.
- list: The input list.

Returns:
The list of transformed elements.

Examples:
let inputs = [ "a"; "bbb"; "cc" ]

inputs |> List.map (fun x -> x.Length)
// Evaluates to [ 1; 3; 2 ]

Full name: Microsoft.FSharp.Collections.ListModule.map
Assembly: FSharp.Core.dll

這項增強功能可讓您更輕鬆地以互動方式探索及瞭解 F# 連結庫。

如需詳細資訊,請參閱 官方 devblog

互動式和已編譯的預處理器指示詞

當您在 F# Interactive 中編譯程式代碼時,不論您是以互動方式執行還是執行腳本,都定義 INTERACTIVE 符號。 當您在編譯程式中編譯程式代碼時,會定義符號 COMPILED 。 因此,如果程式代碼在編譯和互動式模式中必須不同,您可以使用這些預處理器指示詞進行條件式編譯,以判斷要使用哪一個。 例如:

#if INTERACTIVE
// Some code that executes only in FSI
// ...
#endif

在 Visual Studio 中使用 F# Interactive

若要透過 Visual Studio 執行 F# Interactive,您可以按兩下標示為 F# Interactive 的適當工具列按鈕,或使用 按鍵 Ctrl+Alt+F。 這樣做會開啟互動式視窗,這是執行 F# 互動式工作階段的工具視窗。 您也可以選取想要在互動式視窗中執行的一些程式代碼,並按 Alt+Enter 鍵組合。 F# Interactive 會在標示 為 F# Interactive 的工具視窗中啟動。 當您使用此按鍵組合時,請確定編輯器視窗具有焦點。

無論您使用的是控制台或 Visual Studio,命令提示字元隨即出現,解釋器會等候您的輸入。 您可以輸入程式代碼,就像在程式碼檔案中一樣。 若要編譯和執行程序代碼,請輸入兩個分號 (;;; ) 以終止一行或數行輸入。

F# Interactive 會嘗試編譯程式代碼,如果成功,它會執行程式碼,並列印其編譯之類型和值的簽章。 如果發生錯誤,解釋器會列印錯誤訊息。

在相同會話中輸入的程式代碼可以存取先前輸入的任何建構,因此您可以建置程式。 工具視窗中的廣泛緩衝區可讓您視需要將程式代碼複製到檔案中。

在 Visual Studio 中執行時,F# Interactive 會獨立於您的項目執行,因此,除非您將函式的程式代碼複製到互動式視窗中,否則您無法使用 F# Interactive 專案中定義的建構。

您可以藉由調整設定來控制 F# Interactive 命令行自變數(選項)。 在 [ 工具] 功能表上,選取 [ 選項...],然後展開 [F# 工具]。 您可以變更的兩個設定是 F# 互動式選項和 64 位 F# 互動式 設定,只有在您在 64 位電腦上執行 F# Interactive 時才相關。 此設定會決定是否要執行專用的64位版本 fsi.exefsianycpu.exe,而該版本會使用電腦架構來判斷是否要以32位或64位進程的形式執行。

標題 說明
F# Interactive 選項 描述 F# Interactive 的命令列語法和選項,fsi.exe。