Parametreler ve Bağımsız Değişkenler

Bu konuda, parametreleri tanımlamaya ve bağımsız değişkenleri işlevlere, yöntemlere ve özelliklere geçirmeye yönelik dil desteği açıklanmaktadır. Başvuruya göre geçirme ve değişken sayıda bağımsız değişken alabilen yöntemleri tanımlama ve kullanma hakkında bilgiler içerir.

Parametreler ve Bağımsız Değişkenler

parametresi terimi, sağlanması beklenen değerlerin adlarını açıklamak için kullanılır. Bağımsız değişken terimi, her parametre için sağlanan değerler için kullanılır.

Parametreler tanımlama grubu veya curried biçiminde ya da ikisinin bir bileşiminde belirtilebilir. Bağımsız değişkenleri açık bir parametre adı kullanarak geçirebilirsiniz. Yöntemlerin parametreleri isteğe bağlı olarak belirtilebilir ve varsayılan değer verilebilir.

Parametre Desenleri

İşlevlere ve yöntemlere sağlanan parametreler genellikle boşluklarla ayrılmış desenlerdir. Bu, ilke olarak İfadeleri Eşleştir bölümünde açıklanan desenlerden herhangi birinin bir işlev veya üye için parametre listesinde kullanılabildiği anlamına gelir.

Yöntemler genellikle geçen bağımsız değişkenlerin tanımlama grubu biçimini kullanır. Bu, tanımlama grubu biçimi bağımsız değişkenlerin .NET yöntemlerinde geçiriliş biçimiyle eşleşdiğinden diğer .NET dillerinin perspektifinden daha net bir sonuç elde eder.

Curried formu genellikle bağlamalar kullanılarak let oluşturulan işlevlerle kullanılır.

Aşağıdaki sahte kod, tanımlama grubu ve curried bağımsız değişkenlerin örneklerini gösterir.

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

Birleştirilmiş formlar, bazı bağımsız değişkenler tanımlama listelerinde olduğunda ve bazıları olmadığında mümkündür.

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

Diğer desenler parametre listelerinde de kullanılabilir, ancak parametre deseni tüm olası girişlerle eşleşmiyorsa, çalışma zamanında tamamlanmamış bir eşleşme olabilir. Özel durum MatchFailureException , bir bağımsız değişkenin değeri parametre listesinde belirtilen desenler ile eşleşmediğinde oluşturulur. Bir parametre deseni eksik eşleşmelere izin verdiğinde derleyici bir uyarı verir. En az bir diğer desen genellikle parametre listeleri için yararlıdır ve bu joker karakter desenidir. Yalnızca sağlanan bağımsız değişkenleri yoksaymak istediğinizde parametre listesinde joker karakter desenini kullanırsınız. Aşağıdaki kod, bağımsız değişken listesinde joker karakter deseninin kullanımını gösterir.

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

Joker karakter deseni, aşağıdaki kodda olduğu gibi normalde dize dizisi olarak sağlanan komut satırı bağımsız değişkenleriyle ilgilenmediğiniz durumlarda, programın ana giriş noktasında olduğu gibi, geçirilen bağımsız değişkenlere ihtiyacınız olmadığında yararlı olabilir.

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

Bazen bağımsız değişkenlerde kullanılan diğer desenler as , ayrımcı birleşimler ve etkin desenlerle ilişkili desen ve tanımlayıcı desenleridir. Tek durumlu ayrımcı birleşim desenini aşağıdaki gibi kullanabilirsiniz.

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

Çıktı aşağıdaki gibidir:

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

Etkin desenler, aşağıdaki örnekte olduğu gibi bir bağımsız değişkeni istenen biçime dönüştürürken parametre olarak yararlı olabilir:

type Point = { x : float; y : float }

let (| Polar |) { x = x; y = y} =
    ( sqrt (x*x + y*y), System.Math.Atan (y/ x) )

let radius (Polar(r, _)) = r
let angle (Polar(_, theta)) = theta

Aşağıdaki kod satırında gösterildiği gibi, eşleşen bir değeri yerel değer olarak depolamak için deseni kullanabilirsiniz as .

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

Ara sıra kullanılan bir diğer desen, işlevin gövdesi olarak örtük bağımsız değişkende hemen desen eşleşmesi gerçekleştiren bir lambda ifadesi sağlayarak son bağımsız değişkeni adlandırılmamış bırakan bir işlevdir. Buna örnek olarak aşağıdaki kod satırı verilmiştir.

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

Bu kod, genel bir liste alan ve liste boşsa döndüren true bir işlev tanımlar.false Bu tür tekniklerin kullanılması kodun okunmasını zorlaştırabilir.

Bazen, tamamlanmamış eşleşmeler içeren desenler yararlıdır. Örneğin, programınızdaki listelerin yalnızca üç öğe içerdiğini biliyorsanız, parametre listesinde aşağıdakine benzer bir desen kullanabilirsiniz.

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

Eksik eşleşmeleri olan desenlerin kullanımı, hızlı prototip oluşturma ve diğer geçici kullanımlar için en iyi şekilde ayrılmıştır. Derleyici bu tür kodlar için bir uyarı verecek. Bu tür desenler tüm olası girişlerin genel durumunu kapsamaz ve bu nedenle bileşen API'leri için uygun değildir.

Adlandırılmış Bağımsız Değişkenler

Yöntemlerin bağımsız değişkenleri virgülle ayrılmış bağımsız değişken listesindeki konuma göre belirtilebilir veya ad, ardından eşittir işareti ve geçirilecek değer girilerek açıkça bir yönteme geçirilebilir. Ad sağlanarak belirtilirse, bildirimde kullanılandan farklı bir sırada görünebilirler.

Adlandırılmış bağımsız değişkenler, kodu api'deki belirli değişiklik türlerine göre daha okunabilir ve daha uyarlanabilir hale getirir. Örneğin, yöntem parametrelerinin yeniden sıralanması.

Adlandırılmış bağımsız değişkenlere yalnızca yöntemler için izin verilir; bağlı işlevler, işlev değerleri veya lambda ifadeleri için letizin verilmez.

Aşağıdaki kod örneği, adlandırılmış bağımsız değişkenlerin kullanımını gösterir.

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)

Sınıf oluşturucusunun çağrısında, adlandırılmış bağımsız değişkenlerinkine benzer bir söz dizimi kullanarak sınıfın özelliklerinin değerlerini ayarlayabilirsiniz. Aşağıdaki örnekte bu söz dizimi gösterilmektedir.

 type Account() =
    let mutable balance = 0.0
    let mutable number = 0
    let mutable firstName = ""
    let mutable lastName = ""
    member this.AccountNumber
       with get() = number
       and set(value) = number <- value
    member this.FirstName
       with get() = firstName
       and set(value) = firstName <- value
    member this.LastName
       with get() = lastName
       and set(value) = lastName <- value
    member this.Balance
       with get() = balance
       and set(value) = balance <- value
    member this.Deposit(amount: float) = this.Balance <- this.Balance + amount
    member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount


let account1 = new Account(AccountNumber=8782108,
                           FirstName="Darren", LastName="Parker",
                           Balance=1543.33)

Daha fazla bilgi için bkz . Oluşturucular (F#).

Özellik ayarlayıcılarını çağırmak için kullanılan aynı teknik, nesne döndüren herhangi bir yöntem (fabrika yöntemleri gibi) için de geçerlidir:

type Widget() =
    member val Width = 1 with get,set
    member val Height = 1 with get,set

type WidgetFactory =
    static member MakeNewWidget() =
         new Widget()
    static member AdjustWidget(w: Widget) =
         w
let w = WidgetFactory.MakeNewWidget(Width=10)
w.Width // = 10
w.Height // = 1
WidgetFactory.AdjustWidget(w, Height=10)
w.Height // = 10

Bu üyelerin herhangi bir rastgele iş gerçekleştirebileceğini unutmayın; söz dizimi, son değeri döndürmeden önce özellik ayarlayıcılarını çağırmak için etkili bir şekilde kısa bir işlemdir.

İsteğe Bağlı Parametreler

Parametre adının önünde bir soru işareti kullanarak yöntem için isteğe bağlı bir parametre belirtebilirsiniz. İsteğe bağlı parametreler F# seçenek türü olarak yorumlanır, böylece ve Noneile Some bir match ifade kullanarak bunları seçenek türlerinin sorgulandığı normal şekilde sorgulayabilirsiniz. İsteğe bağlı parametrelere yalnızca üyeler üzerinde izin verilir, bağlamalar kullanılarak let oluşturulan işlevlerde izin verilmez.

Veya gibi ?arg=None?arg=Some(3)?arg=argparametre adına göre yöntemine mevcut isteğe bağlı değerleri geçirebilirsiniz. Bu, isteğe bağlı bağımsız değişkenleri başka bir yönteme geçiren bir yöntem oluştururken yararlı olabilir.

İsteğe bağlı bağımsız değişkenin varsayılan değerini ayarlayan bir işlevi defaultArgde kullanabilirsiniz. İşlev, defaultArg isteğe bağlı parametreyi ilk bağımsız değişken, varsayılan değeri ise ikinci bağımsız değişken olarak alır.

Aşağıdaki örnekte isteğe bağlı parametrelerin kullanımı gösterilmektedir.

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)
let conn4 = Connection(?duplex0 = None)
let conn5 = Connection(?duplex0 = Some(Full))

let optionalDuplexValue : option<DuplexType> = Some(Half)
let conn6 = Connection(?duplex0 = optionalDuplexValue)

Çıktı aşağıdaki gibidir:

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

C# ve Visual Basic birlikte çalışma amaçları doğrultusunda, çağıranların isteğe bağlı olarak bir bağımsız değişken görmesi için F# dilinde öznitelikleri [<Optional; DefaultParameterValue<(...)>] kullanabilirsiniz. Bu, bağımsız değişkeni C# dilinde olduğu gibi isteğe bağlı olarak tanımlamaya eşdeğerdir MyMethod(int i = 3).

open System
open System.Runtime.InteropServices
type C =
    static member Foo([<Optional; DefaultParameterValue("Hello world")>] message) =
        printfn $"{message}"

Varsayılan parametre değeri olarak yeni bir nesne de belirtebilirsiniz. Örneğin, üyenin Foo giriş olarak isteğe bağlı CancellationToken bir girişi olabilir:

open System.Threading
open System.Runtime.InteropServices
type C =
    static member Foo([<Optional; DefaultParameterValue(CancellationToken())>] ct: CancellationToken) =
        printfn $"{ct}"

bağımsız değişken DefaultParameterValue olarak verilen değerin parametresinin türüyle eşleşmesi gerekir. Örneğin, aşağıdakilere izin verilmez:

type C =
    static member Wrong([<Optional; DefaultParameterValue("string")>] i:int) = ()

Bu durumda, derleyici bir uyarı oluşturur ve her iki özniteliği de tamamen yoksayar. Varsayılan değerin null tür açıklamalı olması gerektiğini, aksi takdirde derleyicinin yanlış tür çıkardığını unutmayın; örneğin. [<Optional; DefaultParameterValue(null:obj)>] o:obj

Başvuruya Göre Geçirme

Bir F# değerini başvuruya göre geçirmek, yönetilen işaretçi türleri olan byrefs'i içerir. Hangi türün kullanılacağına ilişkin yönergeler aşağıdaki gibidir:

  • İşaretçiyi yalnızca okumanız gerekiyorsa kullanın inref<'T> .
  • yalnızca işaretçiye yazmanız gerekiyorsa kullanın outref<'T> .
  • İşaretçiden hem okumanız hem de işaretçiye yazmanız gerekiyorsa kullanın byref<'T> .
let example1 (x: inref<int>) = printfn $"It's %d{x}"

let example2 (x: outref<int>) = x <- x + 1

let example3 (x: byref<int>) =
    printfn $"It's %d{x}"
    x <- x + 1

let test () =
    // No need to make it mutable, since it's read-only
    let x = 1
    example1 &x

    // Needs to be mutable, since we write to it
    let mutable y = 2
    example2 &y
    example3 &y // Now 'y' is 3

Parametre bir işaretçi olduğundan ve değer değiştirilebilir olduğundan, değerdeki tüm değişiklikler işlevin yürütülmesinden sonra korunur.

Parametreleri .NET kitaplık yöntemlerinde depolamak out için dönüş değeri olarak bir tanımlama grubu kullanabilirsiniz. Alternatif olarak, parametresini out parametre byref olarak değerlendirebilirsiniz. Aşağıdaki kod örneği her iki yolu da gösterir.

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

Parametre Dizileri

Bazen heterojen türde rastgele sayıda parametre alan bir işlev tanımlamak gerekir. Kullanılabilecek tüm türleri hesaba eklemek için tüm olası aşırı yüklenmiş yöntemleri oluşturmak pratik olmaz. .NET uygulamaları, parametre dizisi özelliği aracılığıyla bu tür yöntemler için destek sağlar. İmzasında parametre dizisi alan bir yöntem, rastgele sayıda parametreyle sağlanabilir. Parametreler bir diziye konur. Dizi öğelerinin türü, işleve geçirilebilen parametre türlerini belirler. ile parametre dizisini System.Object öğe türü olarak tanımlarsanız, istemci kodu herhangi bir türdeki değerleri geçirebilir.

F# dilinde parametre dizileri yalnızca yöntemlerde tanımlanabilir. Modüllerde tanımlanan tek başına işlevlerde veya işlevlerde kullanılamazlar.

özniteliğini ParamArray kullanarak bir parametre dizisi tanımlarsınız. ParamArray Özniteliği yalnızca son parametreye uygulanabilir.

Aşağıdaki kod, hem parametre dizisi alan bir .NET yöntemini çağırmayı hem de bir parametre dizisi alan bir yöntemi olan F# türünde bir türün tanımını gösterir.

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

Bir projede çalıştırıldığında, önceki kodun çıktısı aşağıdaki gibidir:

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

Ayrıca bkz.