2017-03-23 6 views
3

Ich muss ändern und neue Eigenschaft für meine F Sharp-Datensatz hinzufügen. aber dann gibt es Fehler für die vorherigen Instanzen, die ohne dieses neue Feld gemacht werden. Ich habe es als Nullable, aber immer noch der gleiche Fehler auftritt, bitte helfen Sie mir, dies zu lösenOptionale Parameter in Fsharp records

+1

Diese Frage ist viel zu vage zu beantworten, aber ich vermute, die Antwort ist das 'mit' Schlüsselwort –

+0

können Sie etwas Code hinzufügen, um die Q? –

+1

Aktualisieren Sie die vorherigen Instanzen, damit sie das neue Feld verwenden? –

Antwort

7

Ich nehme an, Sie meinen "optional" wie in "ein Feld, das ich nicht bei der Instanziierung des Datensatzes". Allerdings gibt es in F # Records leider kein optionales Feld (oder glücklicherweise je nach Standpunkt). Alle von Ihnen angegebenen Datensatzfelder müssen an dem Punkt vorhanden sein, an dem Sie sie instanziieren.

Siehe auch this closely related question.

Sie können diesen Trade-off betrachten:

  • Verwenden Sie einen Rekord. Jedes Mal, wenn Sie den Datensatz aktualisieren, wird der F # -Compiler schreien und Sie über alle Orte informieren, an denen Sie diesen Datensatz verwendet haben, und Sie müssen jetzt die zusätzlichen Informationen bereitstellen. Die zusätzliche Information kann eine None für die Felder sein, die Sie hinzufügten, wenn sie Optionen sind. Der große Vorteil: Ihr Code selbst muss nicht alle möglichen Fälle von "Was tun, wenn field1 fehlt? Was passiert, wenn field2 auch fehlt?"

  • Verwenden Sie eine Klasse. Wenn Sie die Klasse aktualisieren, erzwingt der F # -Compiler keinerlei Vollständigkeitsüberprüfung der Informationen, die Sie in die Klasse eingeben. (Sie können Datensätze als Klassen anzeigen, in denen alle Felder Konstruktorargumente sind und alle bereitgestellt werden müssen). Daher verursacht das Aktualisieren der Klassendefinition keinen Overhead, aber Ihr Code muss alle fehlenden Werte verarbeiten.

Ich persönlich Aufzeichnungen bevorzugt, nur weil es Kräfte mir die Konsequenzen zu denken, durch ein neues Feld hinzuzufügen.

Es gibt natürlich einen Mittelweg: Sie Datensätze verwenden können, aber alle von ihnen über statische Mitglieder oder etwas instanziiert gleichermaßen:

type Name = 
    { 
     First: string 
     Family: string 
    }   
    static member Create(first, family) = { First = first; Family = family} 

Wenn in Ihrem Code Sie immer Name.Create verwenden, um die Aufzeichnung zu instanziieren Sie können natürlich ein Feld MiddleName hinzufügen, ohne dass ein Verbrauchercode dies bemerkt.

5

Die Option type ist in F # gegenüber Null bevorzugt, aus dem einfachen Grund, dass "nicht initialisierte Variablen" nicht in der funktionalen Denkweise existieren.

Beginnen wir mit dem Erstellen eines Datensatzes, der eine VacationRequest darstellt, die vom Chef genehmigt werden muss.

type VacationRequest = 
    {Name : string 
    Date : DateTime 
    Approval : string option} 

Das Problem mit Ihrem Ansatz besteht darin, dass alle Felder auf dem Bau zugeordnet werden müssen, so dass dies nicht kompiliert werden:

let holiday = 
    {Name = "Funk" 
    Date = DateTime(2020,12,31)} 

Sie können dieses Problem umgehen eine Hilfsfunktion, die implizit setzt der Optionswert

let fillInRequest name date = 
    {Name = name 
    Date = date 
    Approval = None} 

Jetzt können Sie den Datensatz mithilfe der Hilfsfunktion erstellen.

let holiday = fillInRequest "Funk" <| DateTime(2020,12,31) 

War etwas lustig beim Senden des Codes an FSI.

val holiday : VacationRequest = {Name = "Funk"; 
           Date = 31/12/2020 12:00:00 ; 
           Approval = null;} 

Der Chef dann die Anforderung aktualisieren konnte (die Schaffung eines neuen Rekord)

let approvedHoliday = 
    {holiday with Approval = Some "boss' name"} 
val approvedHoliday : VacationRequest = {Name = "Funk"; 
             Date = 31/12/2020 12:00:00 ; 
             Approval = Some "boss' name";} 

oder es zurückschicken unverändert

let betterLuckNextTime = holiday