Frage

Wie entscheiden Sie eine Funktion in einem Modul oder als statisches Element eines bestimmten Typs zwischen dem Schreiben?

Zum Beispiel in der Quellcode von F #, es gibt viele Arten, die zusammen mit einem gleichnamigen Modul definiert sind, wie folgt:

type MyType = // ...

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module MyType = // ...

Warum Sie nicht einfach die Operationen als statische Elemente vom Typ MyType definieren?

War es hilfreich?

Lösung

Hier sind einige Hinweise zu den technischen Unterschieden.

können Module sein ‚open'ed (es sei denn, sie haben RequireQualifiedAccessAttribute). Das heißt, wenn Sie setzen Funktionen (F und G) in einem Modul (M), dann kann man schreiben

open M
... F x ... G x ...

, während mit einer statischen Methode, würden Sie immer schreiben

... M.F x ... M.G x ...

Modulfunktionen können nicht überlastet werden. Funktionen in einem Modul lassen gebunden ist, und lassen Sie gebundenen Funktionen Überlastung nicht zulassen. Wenn Sie möchten, beide in der Lage sein zu nennen

X.F(someInt)
X.F(someInt, someString)

Sie müssen members eines Typs verwenden, die nur mit ‚qualifizierten‘ Anrufe (z type.StaticMember(...) oder object.InstanceMember(...)) arbeiten.

(Gibt es weitere Unterschiede? Ich mich nicht erinnern kann.)

Das sind die wichtigsten technischen Unterschiede, die die Wahl des einen über den anderen zu beeinflussen.

Darüber hinaus gibt es eine gewisse Tendenz in dem F # Runtime (FSharp.Core.dll) Module verwenden, nur für F # -spezifische Typen (die sind in der Regel nicht verwendet, wenn tun Interop mit anderen .NET-Sprachen) und statische Methoden für APIs, die sind sprachneutral. Zum Beispiel werden alle Funktionen mit curried Parameter erscheinen in Modulen (curried Funktionen sind nicht-trivial aus anderen Sprachen zu nennen).

Andere Tipps

In F # ziehe ich ein statisches Element auf einer Art über eine Funktion in einem Modul, wenn ...

  1. Ich habe die Art, unabhängig von dem Element
  2. definieren,
  3. Das Element funktionell ist mit dem Typ im Zusammenhang ich definiere

Zusätzlich zu den anderen Antworten gibt es einen weiteren Fall Module zu verwenden:

Für Werttypen sie helfen können statische Eigenschaften zu definieren, die neu bewertet werden nicht jedes Mal auf sie zugegriffen wird. zum Beispiel:

type [<Struct>] Point =
    val x:float
    val y:float
    new (x,y) = {x=x;y=y}

    static member specialPoint1 = // sqrt is computed every time the property is accessed
        Point (sqrt 0.5 , sqrt 0.5 )

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Point = 

    let specialPoint2 = // sqrt is computed only once when the Module is opened
        Point (sqrt 0.5 , sqrt 0.5 )

Einige große Unterschiede, die ursprünglich nicht erwähnt wurden:

  • Funktionen sind erste Klasse Werte in F #, aber statische Mitglieder nicht. So können Sie objs |> Seq.map Obj.func schreiben, aber man kann nicht objs |> Seq.map Obj.Member schreiben.

  • Die Funktionen können curried werden, aber die Mitglieder nicht.

  • Der Compiler wird Typen automatisch schließen, wenn Sie eine Funktion aufrufen, aber nicht, wenn Sie ein Mitglied berufen. So können Sie let func obj = obj |> Obj.otherFunc schreiben, aber man kann nicht let func obj = obj.Member schreiben.

Da die Mitglieder mehr beschränkt sind, ich in der Regel Funktionen verwenden, es sei denn ich möchte ausdrücklich OOP unterstützen / C #.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top