Кортежи

Последнее обновление: 10.12.2023

Кортеж (tuple) представляет набор упорядоченных значений, которые могут представлять различные типы.

Для определения кортежа набор значений заключатся в скобки и оделяется друг от друга запятой:

let user = ("Tom", 37)

В примере выше кортеж называется user и состоит из двух элементов: строки "Tom" и числа 37.

Как и любые данные, в языке F# кортеж имеет свой тип, который складывается из типа его элементов. И мы можем явным образом указывать тип:

let user: string * int = ("Tom", 37)

Тип string * int указывает, что это кортеж, который состоит из двух элементов. Причем первый элемент должен представлять тип string, а второй - тип int.

Другой пример:

let person: string * int * float * bool = ("Sam", 25, 1.78, true)

Здесь кортеж должен состоять из четырех компонентов, где третий компонент должен представлять тип float, а четвертый - тип bool.

Типы кортежей

Кортежи могут представлять как ссылочные типы - классы, так и типы значений - структуры. Создаваемый по умолчанию кортеж представляет ссылочный тип или класс. Например:

let user = ("Tom", 37)

Здесь кортеж user является ссылочным.

Для создания кортежа-структуры его определение предваряется оператором struct:

let person = struct("Sam", 25)

Если нам надо также указать тип для кортежа-структуры, то в определение типа также входит оператор struct:

let person: struct(string * int) = ("Sam", 25)

Причем при присвоении значения можно не указывать оператор struct.

Получение элементов кортежа

С помощью оператора let можно разложить кортеж на отдельные значения:

let user = ("Tom", 37)
let (name, age) = user
printfn $"Name: {name}  Age: {age}"     // Name: Tom  Age: 37

В данном случае получаем первый компонент кортежа user в значение name, а второй компонент - в значение age.

Если мы хотим получить не все, а только некоторые компоненты кортежа, то для ненужных компонентов нужно указать прочерк:

let user = ("Tom", 37, "Microsoft")
let (name, age, _) = user       // получаем первые два компонента кортежа
printfn $"Name: {name}  Age: {age}"     // Name: Tom  Age: 37

let(_, _, company) = user       // получаем только третий компонент кортежа
printfn $"Company: {company}"     // Company: Microsoft

Кроме того, для ссылочных кортежей доступны две специальные функции: fst (возвращает первый элемент кортежа) и snd (возвращает второй элемент кортежа)

let user = ("Tom", 37)

let name = fst user
let age = snd user
printfn $"Name: {name}  Age: {age}"     // Name: Tom  Age: 37

Следует отметить, что в этом случае кортеж должен иметь только два элемента.

Если производится разложение кортежа-структуры, то перед набором значений указывается оператор struct:

let person: struct(string * int) = ("Sam", 25)

let struct (name, age) = person

Кортеж как параметр функции

Параметр может представлять кортеж. Например:

let user = ("Tom", 37)

let printValues (a, b) =               // определение функции
    printfn $"a = {a}   b = {b}"

printValues user        // a = Tom   b = 37        

Если функция должна принять кортеж в качестве параметра, то параметр определяется с помощью скобок, в которых определяется количество элементов кортежа. То есть в данном случае (a, b) означает, что это будет кортеж из двух элементов. При чем функция автоматически раскладывает передаваемый кортеж на значения a и b.

Но, следует отметить, что определение кортежа в качестве параметра следует отличать от простого определения параметров:

let printValues a  b =  printfn $"a = {a}   b = {b}"

Или определения типизированных параметров:

let printValues (a: string,  b: int) =  printfn $"a = {a}   b = {b}"

В обоих случаях выше мы не можем передать в функцию кортеж.

Если же нам надо явным образом указать тип кортежа, то он, как и в общем случае, указывается через двоеточие после параметра, а сам параметр заключается в скобки:

let user = ("Tom", 37)

let printValues ((a,  b): string * int) =  printfn $"a = {a}   b = {b}"

printValues user        // a = Tom   b = 37 

В данном случае значение для параметра должно представлять двухэлементный кортеж, первый элемент которого - строка, а второй - целое число типа int.

Кортеж как результат метода

Кортеж представляет удобный способ получить из функции несколько значений:

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

let (quotient, remainder) = divRem 15 6

printfn "Результат: %d" quotient    // 2
printfn "Остаток: %d" remainder     // 3  (15-2*6)

Здесь функция divRem принимает два параметра - делимое и делитель и возвращает целочисленный результат деления и остаток от деления. А поскольку функция единовременно может возвратить только одно значение, то объединяем оба значения в кортеж.

Также мы можем явно определить тип возвращаемого кортежа:

let divRem a b : struct(int*int) =
   let x = a / b
   let y = a % b
   struct(x, y)

let struct(quotient, remainder) = divRem 15 6

printfn "Результат: %d" quotient    // 2
printfn "Остаток: %d" remainder     // 3  (15-2*6)

Здесь функция divRem возвращает кортеж-структуру, которая состоит из значений типа int.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850