Aracılığıyla paylaş


İşleç Aşırı Yüklemesi (F#)

Bu konu, bir sınıf ya da kayıt türü ve genel düzeyde aritmetik işleç aşırı açıklamaktadır.

// 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

Notlar

In the previous syntax, the operator-symbol is one of +, -, *, /, =, and so on.parameter-list İşlenen bunlar normal sözdiziminde işleç için sırayı belirtir.method-body Elde edilen değeri oluşturur.

İşlecin işleçleri için statik olmalıdır.Fazla tekli operatörler gibi + ve -, bir tilde işareti kullanmanız gerekir (~), operator-symbol aşağıdaki bildiriminde gösterildiği gibi operatör birli işleç ve değil bir ikili işleci olduğunu belirtmek için.

static member (~-) (v : Vector)

Aşağıdaki kod, yalnızca iki işleç olan bir vector sınıfı gösterir bir tekli eksi, diğeri de bir skalar tarafından çarpma.Örnekte, işleç vektör ve skalar görüntülenme sırasından bağımsız olarak çalışması gerekir çünkü iki tekrar yüklemesi skalar çarpma işlemi için gereklidir.

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())

Yeni işleçler yaratmak

Bütün standart işleçler aşırı yüklenmeye neden olabilir, ancak belirli karakter dizileri dışında yeni operatörler de oluşturabilirsiniz.Allowed operator characters are !, %, &, *, +, -, ., /, <, =, >, ?, @, ^,|, and ~.~ Karakter birli işleç yapma özel bir anlamı vardır ve işleç karakter dizisinin bir parçası değildir.Tüm operatörler tekli, belirtildiği gibi yapılabilmesi için öneki ve Infix işleçleri bu konuda daha sonra.

Kullandığınız tam karakter dizisini bağlı olarak, belirli bir öncelik ve birleşim operatörünüzün sahip olacaktır.Birleşim, sağdan sola veya sağa ya da sola ve aynı düzeyde önceliğe sahip olan işleçler sıra parantez olmadan görünür olduğunda kullanılır.

İşleç karakter . önceliği, kendi sürümünüzü aynı öncelik ve birleşim olarak sıradan çarpma olan çarpma tanımlamak istiyorsanız, örneğin, operators gibi oluşturabilirsiniz, böylece etkilemez .*.

İşleçlerin önceliklerini tüm F# gösteren bir tablo içinde bulunan Simge ve İşleç Başvurusu (F#).

Fazla yüklenmiş işleç adları

F# derleyici bir işleç ifade derlediğinde, bu işleç için derleyici tarafından oluşturulan bir ad içeren bir yöntem oluşturur.Bu yöntem için Microsoft Ara dili (MSIL) hem de yansıma ve IntelliSense görünen addır.Normalde F# kodda bu adları kullanmanız gerekmez.

Standart işleçler aşağıdaki tabloda gösterilmektedir ve karşılık gelen adlar oluşturulamaz.

İşleç

Oluşturulan adı

[]

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

Burada listelenmeyen bir işleç karakter diğer kombinasyonları işleçleri olarak kullanılabilir ve adları aşağıdaki tabloda ayrı ayrı karakterler için birleştirerek oluşur adlara sahip.Örneğin, +! becomes op_PlusBang.

İşleç karakter

Ad

>

Greater

<

Less

+

Plus

-

Minus

*

Multiply

/

Divide

=

Equals

~

Twiddle

%

Percent

.

Dot

&

Amp

|

Bar

@

At

^

Hat

!

Bang

?

Qmark

(

LParen

,

Comma

)

RParen

[

LBrack

]

RBrack

Önek ve iç işleçleri

Önek operatörler beklenen bir işleç veya işlev gibi işlenen önüne yerleştirilecek.İnfix işleç bekleniyor arasında iki işlenen yerleştirilecek.

Önek operatörleri yalnızca belirli işleçleri kullanılabilir.Önek operatörleri her zaman bazı işleçler şunlardır, diğerlerinin iç ya da önek olabilir ve diğer işleçler infix her zaman.İle başlayan işleçleri !, dışında !=ve işleç ~, veya yinelenen dizilerini~, her zaman önek işleçlerdir.The operators +, -, +., -., &, &&, %, and %% can be prefix operators or infix operators.Ekleyerek önek sürümü bu işleçler, iç sürümünden ayırt bir ~ başında tanımlandıktan sonra bir önek işleci.~ Yalnızca tanımlandığında işlecini kullandığınızda kullanılmaz.

Örnek

Aşağıdaki kod bir kesir türünü uygulamak için işleç kullanımı gösterilmektedir.Bir kesir bir pay ve payda bir tarafından temsil edilir.İşlev hcf kesirler azaltmak için kullanılan en yüksek ortak çarpanını belirlemek için kullanılır.

// 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())
  

Genel düzeyde işleçleri

Genel düzeyde işleçleri de tanımlayabilirsiniz.Aşağıdaki kod bir işleç tanımlar +?.

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

Yukarıdaki kod çıktı 12.

Yeni tanımlanan işleçleri yerleşik işlecin üzerinde öncelikli F# için ölçüm kuralları dikte çünkü normal aritmetik işlemleri bu şekilde tanımlayabilirsiniz.

Anahtar sözcük inline genellikle çağıran kodun içine en iyi şekilde tümleşik olan küçük işlevlerdir genel işleçleri ile sık sık kullanılır.Yapma işleç işlevler satır içi statik olarak çözümlenen genel kod üretmek için statik olarak çözümlenen tür parametreleri ile çalışmak için sağlar.Daha fazla bilgi için, bkz. Satır İçi İşlevler (F#) ve Statik Olarak Çözümlenmiş Tür Parametreleri (F#).

Ayrıca bkz.

Diğer Kaynaklar

Üyeler (F#)