共用方式為


元組

元組是一組未命名但已排序的值,可能具有不同型別。 元組可以是參考型別或結構。

語法

(element, ... , element)
struct(element, ... ,element )

備註

上一個語法中的每個元素都有可能是任何有效的 F# 運算式。

範例

元組的範例包含相同或不同型別的配對與三合一等。 下列程式碼說明一些範例。

(1, 2)

// Triple of strings.
("one", "two", "three")

// Tuple of generic types.
(a, b)

// Tuple that has mixed types.
("one", 1, 2.0)

// Tuple of integer expressions.
(a + 1, b + 1)

// Struct Tuple of floats
struct (1.025f, 1.5f)

取得個別值

您可利用模式比對來存取和指派元組元素的名稱,如下列程式碼所示。

let print tuple1 =
   match tuple1 with
    | (a, b) -> printfn "Pair %A %A" a b

您也可透過 let 繫結,利用 match 運算式以外的模式比對來解構元組:

let (a, b) = (1, 2)

// Or as a struct
let struct (c, d) = struct (1, 2)

或者,您可將元組上的模式比對為函式的輸入:

let getDistance ((x1,y1): float*float) ((x2,y2): float*float) =
    // Note the ability to work on individual elements
    (x1*x2 - y1*y2) 
    |> abs 
    |> sqrt

如果您只需要元組的一個元素,可以使用萬用字元 (底線) 來避免為不需要的值建立新名稱。

let (a, _) = (1, 2)

將元素從參考元組複製到結構元組,也十分簡單:

// Create a reference tuple
let (a, b) = (1, 2)

// Construct a struct tuple from it
let struct (c, d) = struct (a, b)

fstsnd 函式 (僅限參考元組) 會分別傳回元組的第一和第二個元素。

let c = fst (1, 2)
let d = snd (1, 2)

沒有內建函式會傳回三合一的第三個元素,但您可輕易寫入一個,如下所示。

let third (_, _, c) = c

一般而言,最好使用模式比對來存取個別元組元素。

使用元組

元組可供您輕鬆地從函式傳回多個值,如下列範例所示。 本範例會執行整數除法,並傳回作業的四捨五入結果,作為元組配對的第一個成員,其餘部分則作為配對的第二個成員。

let divRem a b =
   let x = a / b
   let y = a % b
   (x, y)

若您希望避免一般函式語法所隱含的函式引數之隱含 currying,元組也可作為函式引數使用。

let sumNoCurry (a, b) = a + b

定義 let sum a b = a + b 函式的一般語法可供您定義作為函式第一個引數的部分應用程式之函式,如下列程式碼所示。

let sum a b = a + b

let addTen = sum 10
let result = addTen 95
// Result is 105.

如果使用元組作為參數,會停用 currying。 如需詳細資訊,請參閱函式中的「引數的部分應用程式」。

元組型別的名稱

當您寫出作為元組的型別名稱時,可以使用 * 符號來區分元素。 針對包含 intfloatstring 等 (例如(10, 10.0, "ten")) 的元組,型別會以下列方式寫入。

int * float * string

請注意,建立結構元組型別的型別別名時,必須加上外部括號。

type TupleAlias = string * float
type StructTupleAlias = (struct (string * float))

與 C# 元組的互通

C# 中的元組是結構,相當於 F# 中的結構元組。 若您需要與 C# 互通,就必須使用結構元組。

方法很簡單。 例如,假設您必須將元組傳遞至 C# 類別,然後取用其結果 (同樣也是元組):

namespace CSharpTupleInterop
{
    public static class Example
    {
        public static (int, int) AddOneToXAndY((int x, int y) a) =>
            (a.x + 1, a.y + 1);
    }
}

在 F# 程式碼中,您可接著將結構元組當作參數傳遞,並將結果作為結構元組來取用。

open TupleInterop

let struct (newX, newY) = Example.AddOneToXAndY(struct (1, 2))
// newX is now 2, and newY is now 3

在參考元組與結構元組之間進行轉換

由於參考元組與結構元組使用完全不同的基礎表示法,因此無法以隱含方式轉換。 也就是說,下列這類的程式碼不會進行編譯:

// Will not compile!
let (a, b) = struct (1, 2)

// Will not compile!
let struct (c, d) = (1, 2)

// Won't compile!
let f(t: struct(int*int)): int*int = t

您必須在一個元組上比對模式,並使用構成部分來建構另一個元組。 例如:

// Pattern match on the result.
let (a, b) = (1, 2)

// Construct a new tuple from the parts you pattern matched on.
let struct (c, d) = struct (a, b)

參考元組的編譯形式

本節說明元組在編譯時採用的格式。 除非您的目標是 .NET Framework 3.5 或更舊版本,否則不需要閱讀此處的資訊。

元組會編譯成數個泛型型別之一的物件,這些型別全命名為 System.Tuple,均多載於 Arity 上,或作為型別參數的編號。 當您從 C# 或 Visual Basic 等其他語言檢視元組型別,或使用未留意 F# 建構的工具時,元組型別會以此形式出現。 .NET Framework 4 中引進了 Tuple 型別。 如果您的目標是舊版本的 .NET Framework,則編譯器會使用來自 F# 核心程式庫 2.0 版本的 System.Tuple 版本。 此程式庫中的型別僅適用於以 2.0、3.0 和 3.5 版 .NET Framework 為目標的應用程式。 型別轉送是用來確保 .NET Framework 2.0 與 .NET Framework 4 F# 元件之間的二進位相容性。

結構元組的編譯形式

結構元組 (例如 struct (x, y)) 與參考元組基本上並不相同。 它們會編譯成 ValueTuple 型別、以 Arity 多載,或作為型別參數的編號。 它們相當於 C# 元組Visual Basic 元組,並可雙向互通。

另請參閱