Freigeben über


Interaktive Programmierung mit F#

F# Interactive (dotnet fsi) wird verwendet, um F#-Code interaktiv auf der Konsole auszuführen oder F#-Skripts auszuführen. Dies bedeutet, dass F# Interactive eine REPL (Read, Evaluate, Print Loop = Lesen-Auswerten-Drucken-Schleife) für F# ausführt.

Um F# Interactive über die Konsole auszuführen, führen Sie dotnet fsiaus. Sie finden dotnet fsi in jedem .NET SDK.

Anmerkung

Wenn Sie F# interaktiv unter der .NET Framework-Laufzeit verwenden möchten, müssen die Visual Studio Build Tools oder eine Edition von Visual Studio installiert sein. Rufen Sie den FsiAnyCPU.exe-Befehl über eine "Entwickler-Eingabeaufforderung" auf, oder stellen Sie einfach sicher, dass FsiAnyCPU.exe in der PATH-Umgebungsvariable anstelle der dotnet fsi-Befehlszeile verfügbar ist.

Tooling unterstützt die Definition von Version F# Interactive Runtime:

  • In Visual Studio: In der Menüleiste Tools / Optionen dann F#-Tools / F# Interactive und passen Sie Verwendung von .NET Core Scripting an.
  • In Visual Studio Code (ionide-Erweiterung): Im Befehlsmenü Präferenzen: Benutzereinstellungen öffnen, dann Erweiterungen / F# / FSharp: Fsi-Sdk-Dateipfad.

Informationen zu den verfügbaren Befehlszeilenoptionen finden Sie unter F# Interactive Options.

Direktes Ausführen von Code in F# Interactive

Da F# Interactive eine REPL (Read-eval-print loop) ist, können Sie Code interaktiv darin ausführen. Nachfolgend sehen Sie ein Beispiel für eine interaktive Sitzung, nachdem Sie dotnet fsi über die Befehlszeile ausgeführt haben:

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 = ()

Sie werden zwei Haupt dinge bemerken:

  1. Der Code muss mit einem doppelten Semikolon (;;) beendet werden, damit er ausgewertet wird.
  2. Der Code wird ausgewertet und in einem it-Wert gespeichert. Sie können interaktiv auf it verweisen.

F# Interactive unterstützt auch mehrzeilige Eingaben. Sie müssen Ihre Übermittlung nur mit einem doppelten Semikolon (;;) beenden. Betrachten Sie den folgenden Codeausschnitt, der in F# Interactive eingefügt und dort ausgewertet wurde.

> 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 = ()

>

Die Formatierung des Codes wird beibehalten, und die Eingabe wird durch ein doppeltes Semikolon (;;) beendet. F# Interactive hat dann den Code ausgewertet und die Ergebnisse gedruckt!

Skripting mit F#

Die interaktive Auswertung von Code in F# Interactive kann ein hervorragendes Lerntool sein, aber Sie werden schnell feststellen, dass es nicht so produktiv ist wie das Schreiben von Code in einem normalen Editor. Um die normale Codebearbeitung zu unterstützen, können Sie F#-Skripts schreiben.

Scripts verwenden die Dateierweiterung .fsx. Anstatt Quellcode zu kompilieren und dann später die kompilierte Assembly auszuführen, können Sie einfach dotnet fsi ausführen und den Dateinamen des Skripts des F#-Quellcodes angeben, und F# interaktiv liest den Code und führt ihn in Echtzeit aus. Betrachten Sie beispielsweise das folgende Skript namens Script.fsx:

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

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

Wenn diese Datei auf Ihrem Computer erstellt wird, können Sie sie mit dotnet fsi ausführen und die Ausgabe direkt in Ihrem Terminalfenster anzeigen:

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

F#-Skripts werden nativ in Visual Studio und Visual Studio Codeunterstützt.

Verweisen auf Pakete in F# Interactive

Anmerkung

Das Paketverwaltungssystem ist erweiterbar, erfahren Sie mehr über die Plugins und den Erweiterungsmechanismus.

Seit der 5.0-Version der Sprache unterstützt F# Interactive das Verweisen auf Pakete über einen Erweiterungsmechanismus; sie kann standardmäßig auf NuGet-Pakete mit der #r "nuget:"-Syntax und einer optionalen Version verweisen:

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

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

Wenn keine Version angegeben ist, wird das höchste verfügbare Nicht-Vorschau-Paket verwendet. Um auf eine bestimmte Version zu verweisen, führen Sie die Version über ein Komma ein. Dies kann beim Verweisen auf eine Vorschauversion eines Pakets hilfreich sein. Sehen Sie sich z. B. das folgende Skript an, bei dem eine Vorschauversion von DiffSharp verwendet wird:

#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)}"

Angeben einer Paketquelle

Sie können auch eine Paketquelle mit dem Befehl #i angeben. Im folgenden Beispiel wird eine Remote- und eine lokale Quelle angegeben:

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

Dadurch wird die Auflösungs-Engine unter der Haube ebenfalls dazu angeleitet, die Remotequellen und/oder lokalen Quellen miteinzubeziehen, die einem Skript hinzugefügt wurden.

Sie können beliebig viele Paketverweise in einem Skript angeben.

Anmerkung

Es gibt derzeit eine Einschränkung für Skripts, die Frameworkverweise verwenden (z. B.Microsoft.NET.Sdk.Web oder Microsoft.NET.Sdk.WindowsDesktop). Pakete wie Saturn, Giraffe, WinForms sind nicht verfügbar. Dies wird in Issue #9417 nachverfolgt. WinForms funktioniert weiterhin in der .NET Framework-Version von F# Interactive.

Verwenden Sie das --compilertool:<extensionsfolderpath>-Kennzeichen als Argument für die F#-Interaktive Sitzung (oder in den Einstellungen Ihrer Tools), um zusätzliche Erweiterungen neben denen zu laden, die mit dem SDK und/oder Ihren Tools geliefert werden.

Verweisen auf Assemblys auf einem Datenträger mit F# Interactive

Wenn Sie über eine Assembly auf einem Datenträger verfügen und in einem Skript auf diese Assembly verweisen möchten, können Sie sie mit der #r-Syntax angeben. Betrachten Sie den folgenden Code in einem Projekt, das in MyAssembly.dllkompiliert wurde:

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

Nach der Kompilierung können Sie in einer Datei namens Script.fsx wie folgt darauf verweisen:

#r "path/to/MyAssembly.dll"

printfn $"{MyAssembly.myFunction 10 40}"

Die Ausgabe lautet wie folgt:

dotnet fsi Script.fsx
90

Sie können beliebig viele Assemblyverweise in einem Skript angeben.

Laden anderer Skripts

Bei der Skripterstellung kann es häufig hilfreich sein, unterschiedliche Skripts für verschiedene Aufgaben zu verwenden. Manchmal möchten Sie Code aus einem Skript in einem anderen wiederverwenden. Anstatt die Skriptinhalte zu kopieren und in Ihrer Datei einzufügen, können Sie sie ganz einfach mit #load laden und auswerten.

Angenommen, Sie verfügen über die Datei Script1.fsx:

let square x = x * x

Außerdem über die verbrauchende Datei Script2.fsx:

#load "Script1.fsx"
open Script1

printfn $"%d{square 12}"

Sie können Script2.fsx wie folgt auswerten:

dotnet fsi Script2.fsx
144

Sie können so viele #load-Direktiven in einem Skript angeben, wie Sie möchten.

Anmerkung

Die Deklaration open Script1 ist erforderlich. Dies liegt daran, dass Konstrukte in einem F#-Skript in einem Modul auf oberster Ebene kompiliert werden, das den Namen der Skriptdatei darstellt, in der es sich befindet. Wenn die Skriptdatei einen Kleinbuchstaben wie script3.fsx hat, wird der implizierte Modulname automatisch großgeschrieben, und Sie müssen open Script3verwenden. Wenn Sie möchten, dass ein ladbares Skript Konstrukte in einem bestimmten Namespace des Moduls definiert, können Sie einen Namespace der Moduldeklaration hinzufügen, z. B.:

module MyScriptLibrary

Verwenden des fsi-Objekts im F#-Code

F#-Skripts haben Zugriff auf ein benutzerdefiniertes fsi-Objekt, das die interaktive F#-Sitzung darstellt. Es ermöglicht Ihnen, Elemente wie die Ausgabeformatierung anzupassen. Darüber hinaus können Sie auf diese Weise auf Befehlszeilenargumente zugreifen.

Das folgende Beispiel zeigt, wie Befehlszeilenargumente abgerufen und verwendet werden:

let args = fsi.CommandLineArgs

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

Bei der Auswertung werden alle Argumente ausgegeben. Das erste Argument ist immer der Name des Skripts, das ausgewertet wird:

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

Sie können auch System.Environment.GetCommandLineArgs() verwenden, um auf dieselben Argumente zuzugreifen.

Referenz zu F# Interactive-Anweisungen

Die zuvor erwähnten Anweisungen #r und #load sind nur in F# Interactive verfügbar. Es gibt mehrere Direktiven, die nur in F# Interactive verfügbar sind.

Anweisung Beschreibung
#r "nuget:..." Verweist auf ein Paket von NuGet
#r "extname:..." Verweisen Sie auf ein Paket von der extname-Erweiterung[^1] (z. B. paket)
#r "assembly-name.dll" Verweist auf eine Assembly auf einem Datenträger
#load "file-name.fsx" Liest eine Quelldatei, kompiliert sie und führt sie aus.
#help Zeigt Informationen zu verfügbaren Direktiven oder Dokumentationen für bestimmte Funktionen an.
#I Gibt einen Assemblysuchpfad an (in Anführungszeichen).
#quit Beendet eine F# Interactive-Sitzung.
#time on oder #time off Einzeln angegeben aktiviert bzw. deaktiviert #time die Anzeige von Leistungsinformationen. Wenn on festgelegt ist, überwacht F# Interactive die reale Zeit, die CPU-Zeit sowie Garbage Collection-Informationen für jeden Codeabschnitt, der interpretiert und ausgeführt wird.

[^1]: Weitere Informationen zu F#-interaktiven Erweiterungen.

Wenn Sie Dateien oder Pfade in F# Interactive angeben, wird ein Zeichenfolgenliteral erwartet. Daher müssen Dateien und Pfade in Anführungszeichen stehen. Es gelten die üblichen Escapezeichen. Mit dem Zeichen @ können Sie bewirken, dass F# Interactive eine Zeichenfolge, die einen Pfad enthält, als wörtliche Zeichenfolge interpretiert. F# Interactive ignoriert in diesem Fall alle Escapezeichen.

In anderen Fällen sind Anführungszeichen optional, beginnend mit F# 9.

Erweiterte #help-Direktive

Die #help-Direktive unterstützt jetzt die Anzeige der Dokumentation für bestimmte Funktionen. Sie können den Namen der Funktion direkt übergeben, um Details abzurufen.

#help List.map;;

Die Ausgabe lautet wie folgt:

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

Diese Verbesserung erleichtert das interaktive Durchsuchen und Verstehen von F#-Bibliotheken.

Weitere Informationen finden Sie im offiziellen Entwicklerblog .

Interaktive und kompilierte Präprozessordirektiven

Wenn Sie Code in F# Interactive kompilieren, unabhängig davon, ob Sie interaktiv oder ein Skript ausführen, wird das Symbol INTERACTIVE definiert. Wenn Sie Code im Compiler kompilieren, wird das Symbol COMPILED definiert. Daher, wenn Code in kompilierten und interaktiven Modi unterschiedlich sein muss, können Sie diese Präprozessordirektiven für die bedingte Kompilierung verwenden, um zu bestimmen, welcher verwendet werden soll. Zum Beispiel:

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

Verwenden von F# Interactive in Visual Studio

Um F# Interactive über Visual Studio auszuführen, können Sie auf die entsprechende Symbolleistenschaltfläche mit der Bezeichnung F# Interactiveklicken oder die Tasten STRG+ALT+Fverwenden. Dadurch wird das Interactive-Fenster geöffnet, ein Toolfenster, in dem eine F# Interactive-Sitzung ausgeführt wird. Sie können auch Code auswählen, den Sie im interaktiven Fenster ausführen möchten, und die Tastenkombination Alt+Eingabetastedrücken. F# Interactive beginnt in einem Toolfenster mit der Bezeichnung F# Interactive. Wenn Sie diese Tastenkombination verwenden, stellen Sie sicher, dass das Editorfenster den Fokus hat.

Unabhängig davon, ob Sie die Konsole oder Visual Studio verwenden, wird eine Eingabeaufforderung angezeigt, und der Dolmetscher wartet auf Ihre Eingabe. Sie können Code genauso eingeben, wie Sie es in einer Codedatei tun würden. Um den Code zu kompilieren und auszuführen, geben Sie zwei Semikolons ein (;;), um eine Zeile oder mehrere Eingabezeilen zu beenden.

F# Interactive versucht, den Code zu kompilieren, und wenn dies erfolgreich ist, führt er den Code aus und druckt die Signatur der Typen und Werte, die er kompiliert hat. Wenn Fehler auftreten, druckt der Dolmetscher die Fehlermeldungen.

Der in derselben Sitzung eingegebene Code hat Zugriff auf alle zuvor eingegebenen Konstrukte, sodass Sie Programme erstellen können. Mit einem umfangreichen Puffer im Toolfenster können Sie den Code bei Bedarf in eine Datei kopieren.

Wenn sie in Visual Studio ausgeführt wird, wird F# Interactive unabhängig vom Projekt ausgeführt, sodass Sie beispielsweise keine Konstrukte verwenden können, die in Ihrem Projekt in F# Interactive definiert sind, es sei denn, Sie kopieren den Code für die Funktion in das interaktive Fenster.

Sie können die F#-Interaktiven Befehlszeilenargumente (Optionen) steuern, indem Sie die Einstellungen anpassen. Wählen Sie im Menü Extras den Eintrag Optionen aus, und erweitern Sie anschließend F#-Tools. Die beiden Einstellungen, die Sie ändern können, sind die F# Interactive-Optionen und die Einstellung 64-Bit-F# Interactive, die nur relevant ist, wenn Sie F# Interactive auf einem 64-Bit-Computer ausführen. Diese Einstellung bestimmt, ob Sie die dedizierte 64-Bit-Version von fsi.exe oder fsianycpu.exeausführen möchten, die die Computerarchitektur verwendet, um zu bestimmen, ob sie als 32-Bit- oder 64-Bit-Prozess ausgeführt werden soll.

Titel Beschreibung
F# Interactive-Optionen Beschreibt die Befehlszeilensyntax und Optionen für F# Interactive (fsi.exe)