سؤال

كيف تقرر بين كتابة وظيفة داخل وحدة نمطية أو كعضو ثابت من نوع ما؟

على سبيل المثال، في التعليمات البرمجية المصدرية ل F #، هناك الكثير من الأنواع التي يتم تعريفها مع وحدة نمطية تسمى على قدم المساواة، كما يلي:

type MyType = // ...

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

لماذا لا تحدد ببساطة العمليات كأعضاء ثابت من النوع Mytype؟

هل كانت مفيدة؟

المحلول

فيما يلي بعض الملاحظات حول الفروق التقنية.

الوحدات يمكن أن تكون "مفتوحة" (ما لم يكن لديهم المحاطون باكسيستاتريب). وهذا هو، إذا وضعت الوظائف (F و G) في وحدة (M)، ثم يمكنك الكتابة

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

بينما مع طريقة ثابتة، كنت دائما تكتب

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

لا يمكن تحميل وظائف الوحدة. وبعد تعمل الوظائف في وحدة نمطية، ولا تسمح الوظائف المتدينة بالسماح بالحمولة الزائدة. إذا كنت تريد أن تكون قادرة على الاتصال كليهما

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

عليك أن تستعمل memberق من النوع، الذي يعمل فقط مع المكالمات المؤهلة "(على سبيل المثال type.StaticMember(...) أو object.InstanceMember(...)).

(هل هناك اختلافات أخرى؟ لا أستطيع التذكر.)

هذه هي الاختلافات التقنية الرئيسية التي تؤثر على اختيار واحد على الآخر.

بالإضافة إلى ذلك، هناك بعض الميل في وقت التشغيل F # (Fsharp.core.dll) لاستخدام الوحدات النمطية فقط ل F # - أنواع محددة (التي لا تستخدم عادة عند القيام بالتشخص متعدد اللغات مع لغات .Net الأخرى) والأساليب الثابتة ل APIs هي أكثر لغة -محايد. على سبيل المثال، تظهر جميع الوظائف التي تحتوي على المعلمات التي تظهر في الوحدات النمطية (الوظائف التي لا تتراكمها من لغات أخرى).

نصائح أخرى

في F # أفضل عضو ثابت في نوع فوق وظيفة في وحدة نمطية إذا ...

  1. لا بد لي من تحديد النوع بغض النظر عن العضو
  2. يرتبط العضو وظيفيا بالنوع الذي سأحدده

بالإضافة إلى الإجابات الأخرى هناك حالة واحدة أخرى لاستخدام الوحدات:

بالنسبة لأنواع القيمة التي يمكن أن تساعد في تحديد الخصائص الثابتة التي لا يتم إعادة تقييمها في كل مرة يتم فيها الوصول إليها. علي سبيل المثال:

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 )

بعض العروض الكبيرة التي لم تكن ذكرت أصلا:

  • وظائف هي قيم الدرجة الأولى في F #، ولكن الأعضاء الثابتة ليست كذلك. حتى تتمكن من الكتابة objs |> Seq.map Obj.func لكنك لا تستطيع الكتابة objs |> Seq.map Obj.Member.

  • يمكن أن تكون الوظائف، ولكن الأعضاء لا يمكنهم.

  • سوف يستنتج المحول البرمجي الأنواع تلقائيا عند استدعاء وظيفة، ولكن ليس عند استدعاء عضو. حتى تتمكن من الكتابة let func obj = obj |> Obj.otherFunc لكنك لا تستطيع الكتابة let func obj = obj.Member.

نظرا لأن الأعضاء أكثر تقييدا، فأنا عادة استخدام الوظائف إلا إذا أردت صراحة دعم OOP / C #.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top