التحميل الزائد لعامل التشغيل (F#)

This موضوع describes how إلى التحميل الزائد arithmetic عوامل تشغيل في a فئة أو سجل نوع, و at the عمومي المستوى.

// Overloading an operator as a class or record member. 
static member (operator-symbols) (parameter-list) = 
    method-body
// Overloading an operator at the global level
let [inline] (operator-symbols) parameter-list =
    function-body

ملاحظات

في the السابق بناء الجملة, theoperator-symbolهو واحد of+,-,*,/,=, و so تشغيل. The parameter-list specifies the operands في the ترتيب they appear في the usual بناء الجملة for that عامل. The method-body constructs the resulting القيمة.

عامل التحميلات الزائدة for عوامل تشغيل must be ثابت. Operator التحميلات الزائدة for unary عوامل تشغيل, such كـ + و -, must استخدم a tilde (~) في the operator-symbol إلى indicate that the operator هو a عامل تشغيل أحادي و not a ثنائي operator, كـ shown في the following تعليمات برمجية.

static member (~-) (v : Vector)

The following تعليمات برمجية illustrates a vector فئة that has just الثاني عوامل تشغيل, واحد for unary negation و واحد for multiplication بواسطة a scalar. في مثال، لأنه يجب أن يعمل عامل التشغيل بغض النظر عن الترتيب الذي الموجه و scalar تظهر الحاجة التحميلات الزائدة الثاني لضرب القيم المفردة.

type Vector(x: float, y : float) =
   member this.x = x
   member this.y = y
   static member (~-) (v : Vector) =
     Vector(-1.0 * v.x, -1.0 * v.y)
   static member (*) (v : Vector, a) =
     Vector(a * v.x, a * v.y)
   static member (*) (a, v: Vector) =
     Vector(a * v.x, a * v.y)
   override this.ToString() =
     this.x.ToString() + " " + this.y.ToString()

let v1 = Vector(1.0, 2.0)

let v2 = v1 * 2.0
let v3 = 2.0 * v1

let v4 = - v2

printfn "%s" (v1.ToString())
printfn "%s" (v2.ToString())
printfn "%s" (v3.ToString())
printfn "%s" (v4.ToString())

قم بإنشاء عوامل تشغيل جديد

يمكن زيادة التحميل الجميع قياسي عوامل تشغيل، ولكن يمكن إنشاء عوامل جديدة خارج تسلسلات أحرف معينة. مسموح حرف/ حروف عامل التشغيل!،%، &، *، +،-،.،/، < أو = أو >،؟، @، ^، |، و كيلوبايت. ~ حرف له معنى خاص لجعل أحادية عامل تشغيل، و هو ليس جزء من تسلسل الأحرف عامل التشغيل.

اعتماداً تشغيل تماما حرف تسلسل تستخدمها، سيكون لديك عامل أسبقية معينة و associativity. associativity يمكن أما ترك يمين أو اليمين لليسار و هو المستخدمة في كل مرة تظهر العوامل من نفس المستوى من الأسبقية في تسلسل بدون أقواس.

عامل التشغيل حرف. لا يؤثر على الأسبقية، ذلك، على سبيل المثال، إذا كنت تريد إلى تعريف الإصدار الضرب له نفس الأسبقية و associativity كالضرب العادي الخاص بك، يمكنك إنشاء operaإلىrs مثل. *.

جدول يوضح الأسبقية الجميع عوامل تشغيل في ب # يمكن العثور عليها في الرمز وعامل التشغيل مرجع (F#).

محملة فوق طاقتها عامل التشغيل أسماء

عند تجميع المحول البرمجي F# تعبير عامل تشغيل، فإنه ينشئ أسلوب الذي يحتوي على اسم المترجم الذي تم إنشاؤه لهذا العامل. هذا هو الاسم الذي يظهر في Microsoft Office 2010 Suite المتوسطة لغة (MSIL) الأسلوب، و أيضا في انعكاس و التحسس الذكي. لا عادة ما تحتاج إلى استخدم هذه الأسماء في تعليمات برمجية الخاصة ب #.

يعرض الجدول التالي عوامل تشغيل stوard و المطابقة الخاصة بهم بإنشاء أسماء.

العامل

الاسم المُنشأ

[]

op_Nil

::

op_Cons

+

op_Addition

-

op_Subtraction

*

op_Multiply

/

op_Division

@

op_Append

^

op_Concatenate

%

op_Modulus

&&&

op_BitwiseAnd

|||

op_BitwiseOr

^^^

op_ExclusiveOr

<<<

op_LeftShift

~~~

op_LogicalNot

>>>

op_RightShift

~+

op_UnaryPlus

~-

op_UnaryNegation

=

op_Equality

<=

op_LessThanOrEqual

>=

op_GreaterThanOrEqual

<

op_LessThan

>

op_GreaterThan

?

op_Dynamic

?<-

op_DynamicAssignment

|>

op_PipeRight

<|

op_PipeLeft

!

op_Dereference

>>

op_ComposeRight

<<

op_ComposeLeft

<@ @>

op_Quotation

<@@ @@>

op_QuotationUntyped

+=

op_AdditionAssignment

-=

op_SubtractionAssignment

*=

op_MultiplyAssignment

/=

op_DivisionAssignment

..

op_Range

.. ..

op_RangeStep

يمكن استخدام تركيبات غير ذلك من حرف/ حروف عامل التشغيل التي لم يتم سردها هنا كعوامل و أسماؤها تتكون بواسطة concatenating أسماء حرف/ حروف الفردية من الجدول التالي. على سبيل المثال، +! يصبح op_PlusBang.

عامل تشغيل حرف

infix أو البادئة

الاسم

>

infix

Greater

<

infix

Less

+

infix

Plus

-

infix

Minus

*

infix

Multiply

/

infix

Divide

=

infix

Equals

~

prefix

Twiddle

%

infix

Percent

.

تجاهل

Dot

&

infix

Amp

|

infix

Bar

@

infix

At

^

infix

Hat

!

prefix

Bang

?

prefix

Qmark

(

infix

LParen

,

infix

Comma

)

infix

RParen

[

infix

LBrack

]

infix

RBrack

infix operaإلىrs هي تلك التي يتم توقع إلى وضعها بين جهازي المعاملات. بادئةيتم توقع operaإلىrs إلى وضعه أمام معامل أو المعاملات، مثل دالة كثيرا. بشكل عام، أول حرف من عامل التشغيل تحديد ما إذا كان عامل التشغيل هو infix أو عامل تشغيل نسخ احتياطي بادئة. أحرف عامل التشغيل. وغير مستخدمة $ لتحديد ما إذا كان عامل هو عامل تشغيل infix أو عامل تشغيل نسخ احتياطي بادئة؛ بدلاً من ذلك، الحرف التالي في عامل التشغيل هو المستخدم لتحديد ترتيب هو.

مثال

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

// Determine the highest common factor between
// two positive integers, a helper for reducing
// fractions.
let rec hcf a b =
  if a = 0u then b
  elif a<b then hcf a (b - a)
  else hcf (a - b) b

// type Fraction: represents a positive fraction
// (positive rational number).
type Fraction =
   {
      // n: Numerator of fraction.
      n : uint32
      // d: Denominator of fraction.
      d : uint32
   }

   // Produce a string representation. If the
   // denominator is "1", do not display it.
   override this.ToString() =
      if (this.d = 1u)
        then this.n.ToString()
        else this.n.ToString() + "/" + this.d.ToString()

   // Add two fractions.
   static member (+) (f1 : Fraction, f2 : Fraction) =
      let nTemp = f1.n * f2.d + f2.n * f1.d
      let dTemp = f1.d * f2.d
      let hcfTemp = hcf nTemp dTemp
      { n = nTemp / hcfTemp; d = dTemp / hcfTemp }

   // Adds a fraction and a positive integer.
   static member (+) (f1: Fraction, i : uint32) =
      let nTemp = f1.n + i * f1.d
      let dTemp = f1.d
      let hcfTemp = hcf nTemp dTemp
      { n = nTemp / hcfTemp; d = dTemp / hcfTemp }

   // Adds a positive integer and a fraction.
   static member (+) (i : uint32, f2: Fraction) =
      let nTemp = f2.n + i * f2.d
      let dTemp = f2.d
      let hcfTemp = hcf nTemp dTemp
      { n = nTemp / hcfTemp; d = dTemp / hcfTemp }
   
   // Subtract one fraction from another.
   static member (-) (f1 : Fraction, f2 : Fraction) =
      if (f2.n * f1.d > f1.n * f2.d)
        then failwith "This operation results in a negative number, which is not supported."
      let nTemp = f1.n * f2.d - f2.n * f1.d
      let dTemp = f1.d * f2.d
      let hcfTemp = hcf nTemp dTemp
      { n = nTemp / hcfTemp; d = dTemp / hcfTemp }

   // Multiply two fractions.
   static member (*) (f1 : Fraction, f2 : Fraction) =
      let nTemp = f1.n * f2.n
      let dTemp = f1.d * f2.d
      let hcfTemp = hcf nTemp dTemp
      { n = nTemp / hcfTemp; d = dTemp / hcfTemp }

   // Divide two fractions.
   static member (/) (f1 : Fraction, f2 : Fraction) =
      let nTemp = f1.n * f2.d
      let dTemp = f2.n * f1.d
      let hcfTemp = hcf nTemp dTemp
      { n = nTemp / hcfTemp; d = dTemp / hcfTemp }

   // A full set of operators can be quite lengthy. For example,
   // consider operators that support other integral data types,
   // with fractions, on the left side and the right side for each.
   // Also consider implementing unary operators.

let fraction1 = { n = 3u; d = 4u }
let fraction2 = { n = 1u; d = 2u }
let result1 = fraction1 + fraction2
let result2 = fraction1 - fraction2
let result3 = fraction1 * fraction2
let result4 = fraction1 / fraction2
let result5 = fraction1 + 1u
printfn "%s + %s = %s" (fraction1.ToString()) (fraction2.ToString()) (result1.ToString())
printfn "%s - %s = %s" (fraction1.ToString()) (fraction2.ToString()) (result2.ToString())
printfn "%s * %s = %s" (fraction1.ToString()) (fraction2.ToString()) (result3.ToString())
printfn "%s / %s = %s" (fraction1.ToString()) (fraction2.ToString()) (result4.ToString())
printfn "%s + 1 = %s" (fraction1.ToString()) (result5.ToString())
// Output: 3/4 + 1/2 = 5/4 3/4 - 1/2 = 1/4 3/4 * 1/2 = 3/8 3/4 / 1/2 = 3/2 3/4 + 1 = 7/4 

عوامل تشغيل في المستوى العمومي

يمكنك أيضا تعريف عوامل تشغيل في عمومي مستوى. التالي تعليمات برمجية يحدد عامل تشغيل +؟.

let inline (+?) (x: int) (y: int) = x + 2*y
printf "%d" (10 +? 1)

إخراج أعلاه تعليمات برمجية هو 12.

يمكنك redefفيe عوامل التشغيل الحسابية العادية في هذه الطريقة لأن تملي قواعد scopفيg F# أن حديثا عوامل defفيed الأسبقية المضمن-في العوامل.

الكلمة الأساسية inlineهو غالباً باستخدام عوامل تشغيل العام، الذي غالباً ما الدوال الصغيرة أفضل المتكاملة في استدعاء تعليمات برمجية. إجراء operaإلىr دالات مضمنة أيضا من تلك إلى العمل مع معلمات نوع تم حلها بشكل ثابت إلى إنتاج برمجية عامة حلها بشكل ثابت. للمزيد من المعلومات، راجع موضعي الوظائف (F#) وثابت تم الحل نوع معلمات (F#).

راجع أيضًا:

المبادئ

الأعضاء (F#)