C # und F # haben unterschiedliche Implementierungen der Standardparameter (oder optionalen Parameter).
In der C # -Sprache, wenn Sie dem Argument einen Standardwert hinzufügen, ändern Sie nicht den zugrunde liegenden Typ (ich meine den Typ des Parameters). Tatsächlich optionale Argumente in C # ist ein leichter syntaktischer Zucker:
%Vor%Aber F # implementiert dieses Feature auf andere Weise. Im Gegensatz zu C # werden optionale Argumente von F # auf der Site callee aufgelöst, nicht jedoch auf der Site caller :
%Vor%Diese Implementierung ist absolut sinnvoll und viel leistungsfähiger. C # optionale Argumente beschränkten sich nur auf Kompilierzeitkonstanten (weil optionale Argumente in Assemblymetadaten gespeichert wurden). In F # könnte der Standardwert weniger offensichtlich sein, aber wir können einen beliebigen Ausdruck als Standardwert verwenden. So weit so gut.
F # optionale Argumente, die vom F # -Compiler in Microsoft.FSharp.Core.FSharpOption<'a>
umgewandelt werden, was ein Referenztyp ist. Dies bedeutet, dass jeder Aufruf der Methode mit optionalem Argument in F # zu einer zusätzlichen Zuweisung auf dem verwalteten Kopf führt und zu einem Druck auf die Garbage Collection führt .
Ich mache mir keine Gedanken über den Anwendungscode, aber dieses Verhalten könnte die Leistung von Bibliotheken erheblich beeinträchtigen. Was passiert, wenn eine Bibliotheksmethode mit einem optionalen Argument tausende Male pro Sekunde aufgerufen wird?
Diese Implementierung scheint mir wirklich seltsam zu sein. Aber vielleicht gibt es einige Regeln, die der Bibliothekentwickler vermeiden sollte, diese Funktion zu verwenden, oder das F # -Team wird dieses Verhalten in der zukünftigen Version von F # ändern?
?Nach Unit-Test-Profs, die optionale Argumente sind Referenztyp:
%Vor% Weil niemand in F # Team noch nicht interessant ist beim Zusammenstellen von "einfachen", Option
-ähnlichen diskriminierten Vereinigungen als Werttypen, unterstützt Mustervergleich über solche Vereinigungen und so weiter:)
Denken Sie daran, dass Tupel-Typen in funktionalen Sprachen wie F # (viel mehr als Standardargumente) verwendet werden, aber immer noch in CLR als Verweistypen implementiert sind - niemand kümmert sich um Speicherzuweisung und spezifische GC-Optimierungen.
F # 4.1 hat C # optionale Attributkompatibilität. Wenn Sie jedoch Funktionen entwickeln, die auch von F # konsumiert werden, sollten Sie die reguläre Syntax verwenden:
member this.M (?i : int) =
let iv = defaultArg i 12
iv + 1
F # 4.1 optionale Argumente Dokumentation: Ссылка
Tags und Links f# optional-arguments