İşlevlerFunctions

İşlevler, herhangi bir programlama dilinde program yürütmenin temel birimidir.Functions are the fundamental unit of program execution in any programming language. Diğer dillerde olduğu gibi, bir F# işlevin adı vardır, parametreleri olabilir ve bağımsız değişkenler alabilir ve bir gövdeye sahip olabilir.As in other languages, an F# function has a name, can have parameters and take arguments, and has a body. F#Ayrıca, işlevleri değer olarak davranma, ifadelerde adlandırılmamış işlevleri kullanma, yeni işlevler, curried işlevleri ve kısmi olarak işlevlerin örtük tanımına göre işlev oluşturma gibi işlev programlama yapılarını destekler. işlev bağımsız değişkenlerinin uygulaması.F# also supports functional programming constructs such as treating functions as values, using unnamed functions in expressions, composition of functions to form new functions, curried functions, and the implicit definition of functions by way of the partial application of function arguments.

let anahtar sözcüğünü kullanarak işlevler tanımlarsınız veya işlev özyinelemeli ise let rec anahtar sözcük birleşimi.You define functions by using the let keyword, or, if the function is recursive, the let rec keyword combination.

SözdizimiSyntax

// Non-recursive function definition.
let [inline] function-name parameter-list [ : return-type ] = function-body
// Recursive function definition.
let rec function-name parameter-list = recursive-function-body

AçıklamalarRemarks

İşlev adı , işlevini temsil eden bir tanıtıcıdır.The function-name is an identifier that represents the function. Parametre-listesi , boşluklarla ayrılmış ardışık parametrelerden oluşur.The parameter-list consists of successive parameters that are separated by spaces. Parametreler bölümünde açıklandığı gibi her bir parametre için açık bir tür belirtebilirsiniz.You can specify an explicit type for each parameter, as described in the Parameters section. Belirli bir bağımsız değişken türü belirtmezseniz, derleyici türü işlev gövdesinden çıkarması için çalışır.If you do not specify a specific argument type, the compiler attempts to infer the type from the function body. İşlev gövdesi bir ifadeden oluşur.The function-body consists of an expression. İşlev gövdesini oluşturan ifade, genellikle dönüş değeri olan bir son ifadede yer alan bir dizi ifadeden oluşan bir bileşik ifadedir.The expression that makes up the function body is typically a compound expression consisting of a number of expressions that culminate in a final expression that is the return value. Dönüş türü , ardından bir tür ve isteğe bağlıdır.The return-type is a colon followed by a type and is optional. Dönüş değerinin türünü açıkça belirtmezseniz, derleyici son ifadeden dönüş türünü belirler.If you do not specify the type of the return value explicitly, the compiler determines the return type from the final expression.

Basit bir işlev tanımı aşağıdakine benzer:A simple function definition resembles the following:

let f x = x + 1

Önceki örnekte, işlev adı f, bağımsız değişken türü intolan x, işlev gövdesi x + 1ve dönüş değeri inttüründedir.In the previous example, the function name is f, the argument is x, which has type int, the function body is x + 1, and the return value is of type int.

İşlevler, inlineolarak işaretlenebilir.Functions can be marked inline. inlinehakkında bilgi için bkz. Inline Functions.For information about inline, see Inline Functions.

KapsamScope

Modül kapsamı dışında herhangi bir kapsam düzeyinde bir değer veya işlev adını yeniden kullanmak bir hata değildir.At any level of scope other than module scope, it is not an error to reuse a value or function name. Bir adı yeniden kullanırsanız daha sonra belirtilen ad daha önce belirtilen adı gölgeliyor.If you reuse a name, the name declared later shadows the name declared earlier. Ancak, modüldeki en üst düzey kapsamda adların benzersiz olması gerekir.However, at the top level scope in a module, names must be unique. Örneğin, aşağıdaki kod modül kapsamında göründüğünde bir hata üretir, ancak bir işlev içinde göründüğünde değil:For example, the following code produces an error when it appears at module scope, but not when it appears inside a function:

let list1 = [ 1; 2; 3]
// Error: duplicate definition.
let list1 = []
let function1 =
   let list1 = [1; 2; 3]
   let list1 = []
   list1

Ancak aşağıdaki kod herhangi bir kapsam düzeyinde kabul edilebilir:But the following code is acceptable at any level of scope:

let list1 = [ 1; 2; 3]
let sumPlus x =
// OK: inner list1 hides the outer list1.
   let list1 = [1; 5; 10]
   x + List.sum list1

ParametrelerParameters

Parametrelerin adları, işlev adından sonra listelenir.Names of parameters are listed after the function name. Bir parametre için aşağıdaki örnekte gösterildiği gibi bir tür belirtebilirsiniz:You can specify a type for a parameter, as shown in the following example:

let f (x : int) = x + 1

Bir tür belirtirseniz, parametrenin adını izler ve iki nokta üst üste ile birbirinden ayrılır.If you specify a type, it follows the name of the parameter and is separated from the name by a colon. Parametresinin türünü atlarsanız, parametre türü derleyici tarafından algılanır.If you omit the type for the parameter, the parameter type is inferred by the compiler. Örneğin, aşağıdaki işlev tanımında x bağımsız değişkeni, 1 inttüründe olduğu için int türü olarak algılanır.For example, in the following function definition, the argument x is inferred to be of type int because 1 is of type int.

let f x = x + 1

Ancak derleyici, işlevi mümkün olduğunca genel olarak yapmayı dener.However, the compiler will attempt to make the function as generic as possible. Örneğin, aşağıdaki koda göz önünde yer verilmiştir:For example, note the following code:

let f x = (x, x)

İşlevi herhangi bir türden bağımsız değişkenden bir tanımlama grubu oluşturur.The function creates a tuple from one argument of any type. Tür belirtilmediğinden, işlev herhangi bir bağımsız değişken türüyle kullanılabilir.Because the type is not specified, the function can be used with any argument type. Daha fazla bilgi için bkz. Otomatik Genelleştirme.For more information, see Automatic Generalization.

İşlev GövdeleriFunction Bodies

Bir işlev gövdesi, yerel değişkenlerin ve işlevlerin tanımlarını içerebilir.A function body can contain definitions of local variables and functions. Bu tür değişkenler ve işlevler, geçerli işlevin gövdesinde kapsam içinde ve dışında değil.Such variables and functions are in scope in the body of the current function but not outside it. Hafif sözdizimi seçeneğini etkinleştirdiğinizde, aşağıdaki örnekte gösterildiği gibi bir tanımın bir işlev gövdesinde olduğunu göstermek için girinti kullanmanız gerekir:When you have the lightweight syntax option enabled, you must use indentation to indicate that a definition is in a function body, as shown in the following example:

let cylinderVolume radius length =
    // Define a local value pi.
    let pi = 3.14159
    length * pi * radius * radius

Daha fazla bilgi için bkz. kod biçimlendirme yönergeleri ve ayrıntılı sözdizimi.For more information, see Code Formatting Guidelines and Verbose Syntax.

Dönüş DeğerleriReturn Values

Derleyici, dönüş değerini ve türünü belirleyebilmek için bir işlev gövdesinde son ifadeyi kullanır.The compiler uses the final expression in a function body to determine the return value and type. Derleyici, önceki ifadelerden son ifadenin türünü çıkarmayabilir.The compiler might infer the type of the final expression from previous expressions. Önceki bölümde gösterilen cylinderVolumeişlevinde, pi türü, sabit değer 3.14159 floatolacak şekilde belirlenir.In the function cylinderVolume, shown in the previous section, the type of pi is determined from the type of the literal 3.14159 to be float. Derleyici, floatolacak h * pi * r * r ifade türünü belirleyebilmek için pi türünü kullanır.The compiler uses the type of pi to determine the type of the expression h * pi * r * r to be float. Bu nedenle, işlevin genel dönüş türü float.Therefore, the overall return type of the function is float.

Dönüş değerini açık olarak belirtmek için, kodu aşağıdaki gibi yazın:To specify the return value explicitly, write the code as follows:

let cylinderVolume radius length : float =
   // Define a local value pi.
   let pi = 3.14159
   length * pi * radius * radius

Kod yukarıda yazıldığı için, derleyici tüm işleve float uygular; parametresi parametre türlerine de uygulamak için aşağıdaki kodu kullanın:As the code is written above, the compiler applies float to the entire function; if you mean to apply it to the parameter types as well, use the following code:

let cylinderVolume (radius : float) (length : float) : float

İşlev ÇağırmaCalling a Function

İşlev adını ve ardından boşluk ile ayrılmış bağımsız değişkenleri belirterek işlevleri çağırabilirsiniz.You call functions by specifying the function name followed by a space and then any arguments separated by spaces. Örneğin, silindir Dervolume işlevini çağırmak ve sonucu değer Ses'e atamak için aşağıdaki kodu yazarsınız:For example, to call the function cylinderVolume and assign the result to the value vol, you write the following code:

let vol = cylinderVolume 2.0 3.0

Bağımsız Değişkenlerin Kısmi UygulanmasıPartial Application of Arguments

Belirtilen sayıda bağımsız değişkene daha az bir değer sağlarsanız, kalan bağımsız değişkenleri bekleyen yeni bir işlev oluşturursunuz.If you supply fewer than the specified number of arguments, you create a new function that expects the remaining arguments. Bu bağımsız değişken işleme yöntemi, gibi F#işlevsel programlama dillerinin bir özelliğidir ve olarak adlandırılır.This method of handling arguments is referred to as currying and is a characteristic of functional programming languages like F#. Örneğin, iki kanal boyutu ile çalıştığınızı varsayalım: biri 2,0 radius ve diğeri ise 3,0yarıçapı vardır.For example, suppose you are working with two sizes of pipe: one has a radius of 2.0 and the other has a radius of 3.0. Aşağıdaki gibi kanal hacmini tespit eden işlevler oluşturabilirsiniz:You could create functions that determine the volume of pipe as follows:

let smallPipeRadius = 2.0
let bigPipeRadius = 3.0

// These define functions that take the length as a remaining
// argument:

let smallPipeVolume = cylinderVolume smallPipeRadius
let bigPipeVolume = cylinderVolume bigPipeRadius

Daha sonra, iki farklı boyuttan oluşan çeşitli uzunluklar için gereken ek bağımsız değişkeni sağlamanız gerekir:You would then supply the additional argument as needed for various lengths of pipe of the two different sizes:

let length1 = 30.0
let length2 = 40.0
let smallPipeVol1 = smallPipeVolume length1
let smallPipeVol2 = smallPipeVolume length2
let bigPipeVol1 = bigPipeVolume length1
let bigPipeVol2 = bigPipeVolume length2

Özyinelemeli İşlevlerRecursive Functions

Özyinelemeli işlevler kendilerini çağıran işlevlerdir.Recursive functions are functions that call themselves. Let anahtar sözcüğünü takip eden REC anahtar sözcüğünü belirtmenizi gerektirir.They require that you specify the rec keyword following the let keyword. Herhangi bir işlev çağrısını çağırırın olduğu gibi, işlev gövdesinin içinden özyinelemeli işlevi çağırın.Invoke the recursive function from within the body of the function just as you would invoke any function call. Aşağıdaki özyinelemeli işlev n. fibonaccı numarasını hesaplar.The following recursive function computes the nth Fibonacci number. Fibonaccı numara sırası, Antiquity 'in bilindiği ve ardışık her sayının dizideki önceki iki sayının toplamı olduğu bir sıralamadır.The Fibonacci number sequence has been known since antiquity and is a sequence in which each successive number is the sum of the previous two numbers in the sequence.

let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)

Bazı Özyinelemeli işlevler program yığınını taşımayabilir veya işlevindeki biriktiricileri ve devamlılık kullanımı gibi özel tekniklerin farkında olmak üzere, bunları dikkatli bir şekilde yazmayabilir.Some recursive functions might overflow the program stack or perform inefficiently if you do not write them with care and with awareness of special techniques, such as the use of accumulators and continuations.

İşlev DeğerleriFunction Values

' F#De, tüm işlevler değer olarak değerlendirilir; Aslında, işlev değerleriolarak bilinir.In F#, all functions are considered values; in fact, they are known as function values. İşlevler değerler olduğundan, diğer işlevlerde veya değerlerin kullanıldığı diğer bağlamlarda bağımsız değişkenler olarak kullanılabilirler.Because functions are values, they can be used as arguments to other functions or in other contexts where values are used. Bağımsız değişken olarak bir işlev değeri alan bir işlev örneği aşağıda verilmiştir:Following is an example of a function that takes a function value as an argument:

let apply1 (transform : int -> int ) y = transform y

-> belirtecini kullanarak bir işlev değeri türünü belirtirsiniz.You specify the type of a function value by using the -> token. Bu belirtecin sol tarafında, bağımsız değişkenin türü ve sağ tarafta ise dönüş değeri bulunur.On the left side of this token is the type of the argument, and on the right side is the return value. Önceki örnekte apply1, bir bağımsız değişken olarak bir işlev transform alan, transform bir tamsayı alan ve başka bir tamsayı döndüren bir işlevdir.In the previous example, apply1 is a function that takes a function transform as an argument, where transform is a function that takes an integer and returns another integer. Aşağıdaki kod apply1nasıl kullanacağınızı gösterir:The following code shows how to use apply1:

let increment x = x + 1

let result1 = apply1 increment 100

result değeri, önceki kod çalıştıktan sonra 101 olacaktır.The value of result will be 101 after the previous code runs.

Aşağıdaki örnekte gösterildiği gibi, birden çok bağımsız değişken birbirini izleyen -> belirteçleriyle ayrılır:Multiple arguments are separated by successive -> tokens, as shown in the following example:

let apply2 ( f: int -> int -> int) x y = f x y

let mul x y = x * y

let result2 = apply2 mul 10 20

Sonuç 200 ' dir.The result is 200.

Lambda İfadeleriLambda Expressions

Lambda ifadesi adlandırılmamış bir işlevdir.A lambda expression is an unnamed function. Önceki örneklerde, adlandırılmış işlevleri artırma ve MULtanımlamak yerine Lambda ifadelerini aşağıdaki şekilde kullanabilirsiniz:In the previous examples, instead of defining named functions increment and mul, you could use lambda expressions as follows:

let result3 = apply1 (fun x -> x + 1) 100

let result4 = apply2 (fun x y -> x * y ) 10 20

Lambda ifadelerini fun anahtar sözcüğünü kullanarak tanımlarsınız.You define lambda expressions by using the fun keyword. Lambda ifadesi bir işlev tanımına benzer, ancak = belirteci yerine, bağımsız değişken listesini işlev gövdesinden ayırmak için -> belirteci kullanılır.A lambda expression resembles a function definition, except that instead of the = token, the -> token is used to separate the argument list from the function body. Normal bir işlev tanımında olduğu gibi, bağımsız değişken türleri açıkça çıkarsanamıyor veya belirlenebilir ve lambda ifadesinin dönüş türü, gövdedeki son ifadenin türünden çıkarsanamıyor.As in a regular function definition, the argument types can be inferred or specified explicitly, and the return type of the lambda expression is inferred from the type of the last expression in the body. Daha fazla bilgi için bkz. lambda ifadeleri: fun anahtar sözcüğü.For more information, see Lambda Expressions: The fun Keyword.

İşlev Bileşimi ve Ardışık Düzen OluşturmaFunction Composition and Pipelining

İçindeki F# işlevler diğer işlevlerden oluşabilir.Functions in F# can be composed from other functions. İki işlev işlev1 ve function2 bileşimi, işlev1 uygulamasının function2uygulamasını temsil eden başka bir işlevdir:The composition of two functions function1 and function2 is another function that represents the application of function1 followed the application of function2:

let function1 x = x + 1
let function2 x = x * 2
let h = function1 >> function2
let result5 = h 100

Sonuç 202 ' dir.The result is 202.

Ardışık düzen oluşturma, işlev çağrılarının ardışık işlemler olarak birlikte zincirde olmasını sağlar.Pipelining enables function calls to be chained together as successive operations. Ardışık düzen oluşturma aşağıdaki gibi çalışmaktadır:Pipelining works as follows:

let result = 100 |> function1 |> function2

Sonuç yeniden 202 ' dir.The result is again 202.

Kompozisyon işleçleri iki işlev alır ve bir işlev döndürür; Buna karşılık, işlem hattı işleçleri bir işlevi ve bir bağımsız değişkeni alır ve bir değer döndürür.The composition operators take two functions and return a function; by contrast, the pipeline operators take a function and an argument and return a value. Aşağıdaki kod örneği, işlev imzalarındaki ve kullanımındaki farklılıkları göstererek işlem hattı ve bileşim işleçleri arasındaki farkı gösterir.The following code example shows the difference between the pipeline and composition operators by showing the differences in the function signatures and usage.

// Function composition and pipeline operators compared.

let addOne x = x + 1
let timesTwo x = 2 * x

// Composition operator
// ( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
let Compose2 = addOne >> timesTwo

// Backward composition operator
// ( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
let Compose1 = addOne << timesTwo

// Result is 5
let result1 = Compose1 2

// Result is 6
let result2 = Compose2 2

// Pipelining
// Pipeline operator
// ( |> ) : 'T1 -> ('T1 -> 'U) -> 'U
let Pipeline2 x = addOne x |> timesTwo

// Backward pipeline operator
// ( <| ) : ('T -> 'U) -> 'T -> 'U
let Pipeline1 x = addOne <| timesTwo x

// Result is 5
let result3 = Pipeline1 2

// Result is 6
let result4 = Pipeline2 2

Aşırı Yükleme İşlevleriOverloading Functions

Bir türün yöntemlerini aşırı yükleyebilirsiniz ancak işlevleri kullanamazsınız.You can overload methods of a type but not functions. Daha fazla bilgi için bkz. Yöntemler.For more information, see Methods.

Ayrıca bkz.See also