パラメーターと引数Parameters and Arguments

このトピックでは、パラメーターを定義し、関数、メソッド、およびプロパティに引数を渡すための言語サポートについて説明します。This topic describes language support for defining parameters and passing arguments to functions, methods, and properties. これには、参照渡しの方法に関する情報と、可変個の引数を受け取ることができるメソッドを定義して使用する方法についての情報が含まれます。It includes information about how to pass by reference, and how to define and use methods that can take a variable number of arguments.

パラメーターと引数Parameters and Arguments

Term パラメーター を使用して、指定される値の名前を記述します。The term parameter is used to describe the names for values that are expected to be supplied. Term 引数 は、各パラメーターに指定された値に使用されます。The term argument is used for the values provided for each parameter.

パラメーターは、組またはカリー化形式、またはその2つの組み合わせで指定できます。Parameters can be specified in tuple or curried form, or in some combination of the two. 引数は、明示的なパラメーター名を使用して渡すことができます。You can pass arguments by using an explicit parameter name. メソッドのパラメーターは、省略可能として指定し、既定値を指定できます。Parameters of methods can be specified as optional and given a default value.

パラメーターパターンParameter Patterns

関数およびメソッドに渡すパラメーターは、通常、スペースで区切られたパターンです。Parameters supplied to functions and methods are, in general, patterns separated by spaces. つまり、原則として、関数またはメンバーのパラメーターリストでは、「 Match 式 」で説明されているパターンのいずれかを使用できます。This means that, in principle, any of the patterns described in Match Expressions can be used in a parameter list for a function or member.

メソッドは、通常、引数を渡す組形式を使用します。Methods usually use the tuple form of passing arguments. これにより、他の .NET 言語の観点から、.NET メソッドで引数が渡される方法と組の形式が一致するため、より明確な結果が得られます。This achieves a clearer result from the perspective of other .NET languages because the tuple form matches the way arguments are passed in .NET methods.

カリー化形式は、バインディングを使用して作成された関数で最もよく使用され let ます。The curried form is most often used with functions created by using let bindings.

次の擬似コードは、組とカリー化引数の例を示しています。The following pseudocode shows examples of tuple and curried arguments.

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

一部の引数が組に含まれていて、一部がでない場合は、結合されたフォームを使用できます。Combined forms are possible when some arguments are in tuples and some are not.

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

パラメーターリストで他のパターンを使用することもできますが、パラメーターパターンがすべての可能な入力と一致しない場合は、実行時に不完全な一致が発生する可能性があります。Other patterns can also be used in parameter lists, but if the parameter pattern does not match all possible inputs, there might be an incomplete match at run time. 例外 MatchFailureException は、引数の値がパラメーターリストで指定されたパターンと一致しない場合に生成されます。The exception MatchFailureException is generated when the value of an argument does not match the patterns specified in the parameter list. パラメーターパターンで不完全な一致が許可されている場合、コンパイラは警告を発行します。The compiler issues a warning when a parameter pattern allows for incomplete matches. 少なくとも1つの他のパターンはパラメーターリストに便利で、ワイルドカードパターンです。At least one other pattern is commonly useful for parameter lists, and that is the wildcard pattern. 指定された引数を無視するだけの場合は、パラメーターリストでワイルドカードパターンを使用します。You use the wildcard pattern in a parameter list when you simply want to ignore any arguments that are supplied. 次のコードは、引数リストでワイルドカードパターンを使用する方法を示しています。The following code illustrates the use of the wildcard pattern in an argument list.

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

ワイルドカードパターンは、次のコードのように、通常は文字列配列として指定されているコマンドライン引数を必要としない場合に、プログラムへのメインエントリポイントなど、渡された引数が不要な場合に便利です。The wildcard pattern can be useful whenever you do not need the arguments passed in, such as in the main entry point to a program, when you are not interested in the command-line arguments that are normally supplied as a string array, as in the following code.

let main _ =
    printfn "Entry point!"

引数で使用されるその他のパターンとしては、 as パターン、および判別共用体とアクティブパターンに関連付けられた識別子パターンがあります。Other patterns that are sometimes used in arguments are the as pattern, and identifier patterns associated with discriminated unions and active patterns. 次のように、単一ケース判別共用体パターンを使用できます。You can use the single-case discriminated union pattern as 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

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

出力は次のとおりです。The output is as follows.

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

アクティブパターンは、次の例のように、引数を目的の形式に変換するときなどに、パラメーターとして役立ちます。Active patterns can be useful as parameters, for example, when transforming an argument into a desired format, as in the following example:

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

as次のコード行に示すように、パターンを使用して、一致した値をローカル値として格納することができます。You can use the as pattern to store a matched value as a local value, as is shown in the following line of code.

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

場合によって使用されるもう1つのパターンは、関数の本体として、暗黙的な引数に対してパターン一致を直ちに実行するラムダ式を指定することによって、最後の引数を無名のままにする関数です。Another pattern that is used occasionally is a function that leaves the last argument unnamed by providing, as the body of the function, a lambda expression that immediately performs a pattern match on the implicit argument. 例として、次のコード行があります。An example of this is the following line of code.

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

このコードは、ジェネリックリストを受け取り、リストが空の場合はを返し、それ以外の場合はを返す関数を定義し true false ます。This code defines a function that takes a generic list and returns true if the list is empty, and false otherwise. このような手法を使用すると、コードが読みにくくなる可能性があります。The use of such techniques can make code more difficult to read.

場合によっては、不完全な一致を含むパターンが役に立つことがあります。たとえば、プログラムのリストに3つの要素しかないことがわかっている場合は、パラメーターリストで次のようなパターンを使用できます。Occasionally, patterns that involve incomplete matches are useful, for example, if you know that the lists in your program have only three elements, you might use a pattern like the following in a parameter list.

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

一致しないパターンを使用すると、簡単なプロトタイプ作成やその他の一時的な使用に適しています。The use of patterns that have incomplete matches is best reserved for quick prototyping and other temporary uses. コンパイラは、このようなコードに対して警告を発行します。The compiler will issue a warning for such code. このようなパターンでは、可能なすべての入力の一般的なケースに対応できないため、コンポーネント Api には適していません。Such patterns cannot cover the general case of all possible inputs and therefore are not suitable for component APIs.

名前付き引数Named Arguments

メソッドの引数は、コンマで区切られた引数リスト内の位置によって指定できます。また、名前を指定してメソッドに明示的に渡すこともできます。その後、等号と渡される値を指定します。Arguments for methods can be specified by position in a comma-separated argument list, or they can be passed to a method explicitly by providing the name, followed by an equal sign and the value to be passed in. 名前を指定して指定した場合は、宣言で使用されているものとは異なる順序で表示されます。If specified by providing the name, they can appear in a different order from that used in the declaration.

名前付き引数を使用すると、メソッドパラメーターの並べ替えなど、API の特定の種類の変更にコードを読みやすくし、適応性を高めることができます。Named arguments can make code more readable and more adaptable to certain types of changes in the API, such as a reordering of method parameters.

名前付き引数は、バインドされていない let 関数、関数値、またはラムダ式ではなく、メソッドに対してのみ使用できます。Named arguments are allowed only for methods, not for let-bound functions, function values, or lambda expressions.

名前付き引数の使用方法を次のコード例に示します。The following code example demonstrates the use of named arguments.

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)

クラスコンストラクターの呼び出しでは、名前付き引数と同様の構文を使用して、クラスのプロパティの値を設定できます。In a call to a class constructor, you can set the values of properties of the class by using a syntax similar to that of named arguments. 次の例は、この構文を示しています。The following example shows this syntax.

 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",

詳細については、「 コンストラクター (F #)」を参照してください。For more information, see Constructors (F#).

省略可能のパラメーターOptional Parameters

パラメーター名の前に疑問符を使用して、メソッドの省略可能なパラメーターを指定できます。You can specify an optional parameter for a method by using a question mark in front of the parameter name. 省略可能なパラメーターは F # のオプションの型として解釈されるので、およびで式を使用して、オプションの型のクエリを実行する通常の方法でクエリを実行でき match Some None ます。Optional parameters are interpreted as the F# option type, so you can query them in the regular way that option types are queried, by using a match expression with Some and None. 省略可能なパラメーターは、バインディングを使用して作成された関数ではなく、メンバーに対してのみ許可され let ます。Optional parameters are permitted only on members, not on functions created by using let bindings.

またはなどのパラメーター名を使用して、既存の省略可能な値をメソッドに渡すことができ ?arg=None ?arg=Some(3) ?arg=arg ます。You can pass existing optional values to method by parameter name, such as ?arg=None or ?arg=Some(3) or ?arg=arg. これは、オプションの引数を別のメソッドに渡すメソッドを構築する場合に便利です。This can be useful when building a method that passes optional arguments to another method.

また、 defaultArg 省略可能な引数の既定値を設定する関数を使用することもできます。You can also use a function defaultArg, which sets a default value of an optional argument. 関数は、省略可能なパラメーターを最初の引数として defaultArg 受け取り、既定値を2番目の引数として受け取ります。The defaultArg function takes the optional parameter as the first argument and the default value as the second.

省略可能なパラメーターの使用例を次に示します。The following example illustrates the use of optional parameters.

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)

出力は次のとおりです。The output is as follows.

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# と Visual Basic の相互運用を目的として、F # の属性を使用して、 [<Optional; DefaultParameterValue<(...)>] 呼び出し元が引数を省略可能として認識できるようにすることができます。For the purposes of C# and Visual Basic interop you can use the attributes [<Optional; DefaultParameterValue<(...)>] in F#, so that callers will see an argument as optional. これは、のように、C# では引数を省略可能として定義することと同じです MyMethod(int i = 3)This is equivalent to defining the argument as optional in C# as in MyMethod(int i = 3).

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

また、新しいオブジェクトを既定のパラメーター値として指定することもできます。You can also specify a new object as a default parameter value. たとえば、メンバーは Foo 省略可能なを入力として持つことができ CancellationToken ます。For example, the Foo member could have an optional CancellationToken as input instead:

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

の引数として指定された値は、 DefaultParameterValue パラメーターの型と一致する必要があります。The value given as argument to DefaultParameterValue must match the type of the parameter. たとえば、次は許可されていません。For example, the following is not allowed:

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

この場合、コンパイラは警告を生成し、両方の属性を完全に無視します。In this case, the compiler generates a warning and will ignore both attributes altogether. 既定値には型指定の注釈を付ける必要があることに注意し null てください。そうでない場合、コンパイラは正しくない型を推論します。 [<Optional; DefaultParameterValue(null:obj)>] o:objNote that the default value null needs to be type-annotated, as otherwise the compiler infers the wrong type, i.e. [<Optional; DefaultParameterValue(null:obj)>] o:obj.

参照渡しPassing by Reference

参照による F # 値の引き渡しには、マネージポインター型である byrefが含まれます。Passing an F# value by reference involves byrefs, which are managed pointer types. 使用する種類に関するガイダンスは次のとおりです。Guidance for which type to use is as follows:

  • inref<'T>ポインターのみを読み取る必要がある場合は、を使用します。Use inref<'T> if you only need to read the pointer.
  • outref<'T>ポインターへの書き込みのみが必要な場合は、を使用します。Use outref<'T> if you only need to write to the pointer.
  • byref<'T>ポインターの読み取りと書き込みの両方を行う必要がある場合は、を使用します。Use byref<'T> if you need to both read from and write to the pointer.
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'd %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

パラメーターはポインターであり、値は変更可能であるため、値に対する変更は、関数の実行後も保持されます。Because the parameter is a pointer and the value is mutable, any changes to the value are retained after the execution of the function.

戻り値としてタプルを使用して、 out .net ライブラリメソッドに任意のパラメーターを格納できます。You can use a tuple as a return value to store any out parameters in .NET library methods. または、パラメーターを out パラメーターとして扱うこともでき byref ます。Alternatively, you can treat the out parameter as a byref parameter. 両方の方法を次のコード例に示します。The following code example illustrates both ways.

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

パラメーター配列Parameter Arrays

場合によっては、異種型の任意の数のパラメーターを受け取る関数を定義する必要があります。Occasionally it is necessary to define a function that takes an arbitrary number of parameters of heterogeneous type. すべてのオーバーロードされたメソッドを作成して、使用可能なすべての型を考慮することは実用的ではありません。It would not be practical to create all the possible overloaded methods to account for all the types that could be used. .NET 実装では、パラメーター配列機能を使用して、このようなメソッドをサポートしています。The .NET implementations provide support for such methods through the parameter array feature. シグネチャでパラメーター配列を受け取るメソッドには、任意の数のパラメーターを指定できます。A method that takes a parameter array in its signature can be provided with an arbitrary number of parameters. パラメーターは配列に格納されます。The parameters are put into an array. 配列要素の型によって、関数に渡すことができるパラメーターの型が決まります。The type of the array elements determines the parameter types that can be passed to the function. 要素の型としてを使用してパラメーター配列を定義すると System.Object 、クライアントコードは任意の型の値を渡すことができます。If you define the parameter array with System.Object as the element type, then client code can pass values of any type.

F # では、パラメーター配列はメソッドでのみ定義できます。In F#, parameter arrays can only be defined in methods. これらは、モジュールで定義されているスタンドアロン関数または関数では使用できません。They cannot be used in standalone functions or functions that are defined in modules.

パラメーター配列は、属性を使用して定義し ParamArray ます。You define a parameter array by using the ParamArray attribute. 属性は、 ParamArray 最後のパラメーターにのみ適用できます。The ParamArray attribute can only be applied to the last parameter.

次のコードは、パラメーター配列を受け取る .NET メソッドと、パラメーター配列を受け取るメソッドを持つ F # の型の定義の両方を呼び出す方法を示しています。The following code illustrates both calling a .NET method that takes a parameter array and the definition of a type in F# that has a method that takes a parameter array.

open System

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

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)

プロジェクト内で実行すると、前のコードの出力は次のようになります。When run in a project, the output of the previous code is as follows:

a 1 10 Hello world 1 True
"Hello world"

関連項目See also