パラメーターと引数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

パラメーターという用語は、指定される値の名前を記述するために使用されます。The term parameter is used to describe the names for values that are expected to be supplied. 引数という用語は、各パラメーターに指定された値に使用されます。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. つまり、原則として、「一致式」で説明されているパターンは、関数またはメンバーのパラメーター・リストで使用できます。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.

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

引数で使用されるパターン、および判別共用体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
    text.[p0..p1]

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",
                           Balance=1543.33)

詳細については、「コンストラクター (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=argYou 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# 値を渡すと、マネージ ポインター型であるbyrefsが使用されます。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.

戻り値としてタプルを使用して、.NET ライブラリoutメソッドにパラメーターを格納できます。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

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

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

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

関連項目See also