Кортежи
Кортеж представляет собой группирование неназванных, но упорядоченных значений, возможно, различных типов. Кортежи могут быть ссылочными типами или структурами.
Синтаксис
(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
Вы также можете деконструировать кортеж с помощью сопоставления шаблонов match
за пределами выражения с помощью let
привязки:
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)
Функции fst
и snd
(только ссылочные кортежи) возвращают первые и второй элементы кортежа соответственно.
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)
Кортежи также можно использовать в качестве аргументов функций, если вы хотите избежать неявного карриинга аргументов функций, подразумеваемых обычным синтаксисом функции.
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.
Использование кортежа в качестве параметра отключает карриирование. Дополнительные сведения см. в разделе "Частичное применение аргументов" в функциях.
Имена типов кортежей
При написании имени типа, который является кортежем, вы используете *
символ для разделения элементов. Для кортежа, состоящего из int
типа , а float
также string
(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#. Tuple
Типы были введены в платформа .NET Framework 4. Если вы используете более раннюю версию платформа .NET Framework, компилятор использует версии System.Tuple
из версии 2.0 основной библиотеки F#. Типы в этой библиотеке используются только для приложений, предназначенных для версий 2.0, 3.0 и 3.5 платформа .NET Framework. Перенаправление типов используется для обеспечения совместимости двоичных файлов между компонентами платформа .NET Framework 2.0 и платформа .NET Framework 4 F#.
Скомпилированный вид кортежей структур
Кортежи структуры (например, struct (x, y)
) существенно отличаются от ссылочных кортежей. Они компилируются в ValueTuple тип, перегружены arity или число параметров типа. Они эквивалентны кортежам C# и кортежам Visual Basic, а также взаимодействуют двунаправленно.