معلمات و وسيطات (F#)

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

معلمات و وسيطات

معلمة مصطلح هو يستخدم لوصف أسماء للقيم التي يتم من المتوقع أن يتم توفيرها. وسيطة المصطلح هو استخدامه بالنسبة للقيم المتوفرة لكل معلمة.

يمكن أن تكون المعلمات المحددة في المجموعة أو curried نموذج، أو في بعض خليط من الاثنين. يمكنك تمرير الوسيطات باستخدام صريحة معلمة اسم. يمكن أن يتم تعيين المعلمات للوظائف كـ اختياري، ومنح القيمة افتراضية.

أنماط معلمة

المعلمات المتوفرة إلى الدالات والأساليب، بشكل عام، والأنماط مفصولة بمسافات. وهذا يعني، في المبدأ، أي من أنماط الموصوفة في تطابق التعبيرات (F#)ليتم استخدامها في قائمة معلمة لدالة أو عضو.

وظائف عادة استخدم شكل المجموعة تمرير الوسيطات. وهذا يحقق نتائج أكثر وضوحاً من منظور اللغات.NET غير ذلك لأن النموذج المجموعة تطابق الطريقة التي يتم تمرير الوسيطات في وظائف.NET.

يستخدم النموذج curried غالباً بإنشاء دالات بواسطة استخدام letالروابط.

ما يلي عبارة عن أمثلة للمجموعة و curried الوسيطات.

// Tuple form.
member this.SomeMethod(param1, param2) = ...
// Curried form.
let function1 param1 param2 = ...

النماذج المنضمة ممكنة عندما تكون بعض الوسيطات في المجموعات عن و البعض الآخر لا.

let function2 param1 (param2a, param2b) param3 = ...

لمزيد من المعلومات حول استخدم الدالات curried، راجع "تطبيق جزئي" ل الوسيطات.

يمكن أيضا استخدام أنماط غير ذلك في قوائم المعلمات، ولكن إذا كان نقش معلمة غير موجود مطابقة يعد ممكن الجميع إدخالاً، فقد يكون هناك غير كامل مطابقة في وقت التشغيل. استثناء MatchFailureExceptionهو نوع يتم إنشاؤه عند القيمة وسيطة لا تطابق النقوش المحددة في معلمة قائمة. صدور المحول البرمجي تحذير عندما يسمح نقش معلمة التطابقات غير كامل. واحد على الأقل نقش يفيد عادة قوائم المعلمات، و هو نمط أحرف البدل. استخدم حرف البدل نقش في قائمة معلمة عندما تريد تجاهل أية وسائط يتم توفيرها فقط. توضح التعليمة البرمجية التالية استخدام نمط حرف بدل في قائمة وسيطة.

let makeList _ = [ for count in 1 .. 100 -> count * count ]
// The arguments 100 and 200 are ignored.
let list1 = makeList 100
let list2 = makeList 200

يمكن أن يكون نقش بدل مفيداً عندما لا تحتاج الوسيطات التي تم تمريرها، كما في يؤشر الإدخال الرئيسي إلى برنامج، عندما كنت غير مهتما بوسيطات سطر الأوامر التي يتم توفيرها عادة كصفيف سلسلة، كما في تعليمات برمجية التالية.

[<EntryPoint>]
let main _ =
    printfn "Entry point!"
    0

غير ذلك أنماط that are sometimes used في الوسيطات are the as نقش, و معرّف أنماط associated مع discriminated الاتحادات و نشط أنماط. You can استخدم the مفرد-حالة discriminated توحيد نقش كـ follows.

type Slice = Slice of int * int * string

let GetSubstring1 (Slice(p0, p1, text)) = 
    printfn "Data begins at %d and ends at %d in string %s" p0 p1 text
    text.[p0..p1]

let substring = GetSubstring1 (Slice(0, 4, "Et tu, Brute?"))
printfn "Substring: %s" substring

الإخراج هو كما يلي.

Data begins at 0 and ends at 4 in string Et tu, Brute?
Et tu

You can استخدم the as نقش إلى store a matched القيمة كـ a محلي القيمة, كـ هو shown في the following خط of تعليمات برمجية.

let GetSubstring2 (Slice(p0, p1, text) as s) = s

Another نقش that هو used occasionally هو a دالة that leaves the أخير وسيطة unnamed بواسطة providing, كـ the النص الأساسي of the دالة, a lambda تعبير that immediately performs a نقش مطابقة تشغيل the implicit وسيطة. An مثال of this هو the following خط of تعليمات برمجية.

let isNil = function [] -> true | _::_ -> false

This تعليمات برمجية defines a دالة that takes a generic قائمة و إرجاع true if the قائمة هو فارغ, و false otherwise. The استخدم of such techniques can make تعليمات برمجية المزيد difficult إلى read.

Occasionally, أنماط that involve غير كامل التلائمات are useful, for مثال, if you know that the lists في your برنامج have فقط three عناصر, you might استخدم a نقش مثل the following في a معلمة قائمة.

let sum [a; b; c;] = a + b + c

The استخدم of أنماط that have غير كامل التلائمات هو best محجوز for quick prototyping و غير ذلك temporary uses. Such أنماط cannot cover the عام حالة of الجميع possible inputs و therefore are not suitable for مكوّن APIs.

الوسيطات المسماة

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

Passing الوسيطات حسب الاسم makes تعليمات برمجية المزيد readable و المزيد adaptable إلى certain أنواع of التغييرات في the API, such كـ a reordering of أسلوب معلمات.

Named الوسيطات are allowed فقط for وظائف, not for let-حدود دالات, دالة قيم, أو lambda expressions.

The following تعليمات برمجية مثال demonstrates the استخدم of named الوسيطات.

type SpeedingTicket() =
    member this.GetMPHOver(speed: int, limit: int) = speed - limit

let CalculateFine (ticket : SpeedingTicket) =
    let delta = ticket.GetMPHOver(limit = 55, speed = 70)
    if delta < 20 then 50.0 else 100.0

let ticket1 : SpeedingTicket = SpeedingTicket()
printfn "%f" (CalculateFine ticket1)

المعلمات الإختيارية

يمكنك تحديد معامل اختياري لأسلوب بواسطة استخدام علامة الاستفهام أمام اسم المعامل. ويتم تفسير المعلمات الاختيارية كـ F# نوع خيار، حيث يمكنك الاستعلام بالطريقة العادية يطالب أنواع الخيارات، باستخدام matchتعبير مع Someو None. مسموح بالمعلمات الاختيارية فقط تشغيل الأعضاء، وليس تشغيل الدالات التي تم إنشاؤها بواسطة استخدام letالروابط.

يمكنك أيضا استخدام "دالة" defaultArg، أي مجموعات الافتراضي القيمة وسيطة الاختيارية. defaultArgدالة يأخذ معلمة الاختيارية كـ الوسيطة الأولى والقيمة الافتراضية كـ الثاني.

يوضح المثال التالي استخدم المعلمات الاختيارية.

type DuplexType =
    | Full
    | Half

type Connection(?rate0 : int, ?duplex0 : DuplexType, ?parity0 : bool) =
    let duplex = defaultArg duplex0 Full
    let parity = defaultArg parity0 false
    let mutable rate = match rate0 with
                        | Some rate1 -> rate1
                        | None -> match duplex with
                                  | Full -> 9600
                                  | Half -> 4800
    do printfn "Baud Rate: %d Duplex: %A Parity: %b" rate duplex parity

let conn1 = Connection(duplex0 = Full)
let conn2 = Connection(duplex0 = Half)
let conn3 = Connection(300, Half, true)

الإخراج هو كما يلي.

Baud Rate: 9600 Duplex: Full Parity: false
Baud Rate: 4800 Duplex: Half Parity: false
Baud Rate: 300 Duplex: Half Parity: true

التمرير بالمرجع

يدعم F# byrefالكلمة الأساسية التي تحدد أن يتم تمرير معلمة مرجع. وهذا يعني أنه يتم الاحتفاظ بأية تغييرات إلى القيمة بعد تنفيذ دالة. قيم المقدمة إلى byrefيجب أن تكون معلمة mutable. بدلاً من ذلك، يمكنك تمرير مرجع خلايا المناسب نوع.

تمرير حسب المرجع في اللغات.NET evolved كوسيلة إلى بإرجاع القيمة واحد أو المزيد دالة. في F#, يمكنك إرجاع المجموعة لهذا الغرض، أو استخدام خلية مرجع mutable كـ معلمة. byrefأساسا هو توفير معلمة للتوافق مع مكتبات.NET.

يلي أمثلة توضيح استخدم byrefالكلمة الأساسية. لاحظ أنه عند استخدام مرجع خلية معلمة، يجب عليك إنشاء مرجع خلية كقيمة المسماة "و" الاستخدام التي المعلمة، ليس فقط بإضافة refعامل التشغيل كما هو موضح في الاستدعاء أول إلى Incrementفي ما يلي تعليمات برمجية. نظراً لإنشاء مرجع خلية بإنشاء نسخ من القيمة الأساسية، الاستدعاء أول فقط بزيادة قيمة مؤقتة.

type Incrementor(z) =
    member this.Increment(i : int byref) =
       i <- i + z

let incrementor = new Incrementor(1)
let mutable x = 10
// Not recommended: Does not actually increment the variable.
incrementor.Increment(ref x)
// Prints 10.
printfn "%d" x  

let mutable y = 10
incrementor.Increment(&y)
// Prints 11.
printfn "%d" y 

let refInt = ref 10
incrementor.Increment(refInt)
// Prints 11.
printfn "%d" !refInt  

يمكنك استخدام المجموعة كقيمة إرجاع إلى sإلىre أي outمعلمات في وظائف مكتبة.NET. بدلاً من ذلك، يمكن التعامل مع outمعلمة كـ byrefمعلمة. يوضح المثال التالي تعليمات برمجية كلاهما الطرق.

// TryParse has a second parameter that is an out parameter
// of type System.DateTime.
let (b, dt) = System.DateTime.TryParse("12-20-04 12:21:00")

printfn "%b %A" b dt

// The same call, using an address of operator.
let mutable dt2 = System.DateTime.Now
let b2 = System.DateTime.TryParse("12-20-04 12:21:00", &dt2)

printfn "%b %A" b2 dt2

صفائف المعلمة.

ففي بعض الأحيان هو اللازم لتعريف دالة التي تأخذ بعدد عشوائي من معلمات نوع غير المتجانسة. قد لا يكون عمليا لإنشاء الجميع الأساليب overloaded المحتملة الحساب لالجميع أنواع التي يمكن استخدامها. النظام الأساسي.NET توفر الدعم لمثل وظائف من خلال ميزة صفيفة المعلمات. أسلوب الذي يأخذ معلمة ويمكن توفير صفيفة في توقيع الخاصة به باستخدام رقم عشوائي معلمة s. يتم وضع المعلمات في صفيفة. نوع الصفيف تحديد العناصر المعلمة نوع s التي يتم تمريرها إلى دالة. إذا عرفت الصفيف معلمة مع Objectكنوع العنصر، ثم العميل تعليمات برمجية يمكن تمرير قيم من أي نوع.

في F#, يمكن تعريف الصفائف معلمة فقط في الأساليب. لا يمكن استخدامها في وظائف مستقل أو الدالات التي تم تعريفها في الوحدات النمطية.

قم بتحديد صفيفة معلمة بواسطة استخدام السمة ParamArray. ParamArray سمة يمكن فقط تطبيق إلى آخر من معلمة.

يوضح التعليمة البرمجية التالية في كل من استدعاء أسلوب.NET الذي يأخذ صفيفة معلمة و تعريف نوع في F# يحتوي على أسلوب الذي يأخذ صفيفة معلمات.

open System

type X() =
    member this.F([<ParamArray>] args: Object[]) =
        for arg in args do
            printfn "%A" arg

[<EntryPoint>]
let main _ =
    // call a .NET method that takes a parameter array, passing values of various types
    Console.WriteLine("a {0} {1} {2} {3} {4}", 1, 10.0, "Hello world", 1u, true)

    let xobj = new X()
    // call an F# method that takes a parameter array, passing values of various types
    xobj.F("a", 1, 10.0, "Hello world", 1u, true)
    0

يكون الإخراج من تعليمات برمجية السابق كـ التالي:

a 1 10 Hello world 1 True
"a"
1
10.0
"Hello world"
1u
true

راجع أيضًا:

المبادئ

الأعضاء (F#)