Tuplas
Uma tupla é um agrupamento de valores sem nome, mas ordenados, possivelmente de diferentes tipos. As tuplas podem ser tipos de referência ou estruturas.
Sintaxe
(element, ... , element)
struct(element, ... ,element )
Observações
Cada elemento na sintaxe anterior pode ser qualquer expressão F# válida.
Exemplos
Exemplos de tuplas incluem pares, triplos, e assim por diante, do mesmo tipo ou de tipos diferentes. Alguns exemplos são ilustrados no código a seguir.
(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)
Obtenção de Valores Individuais
Você pode usar a correspondência de padrões para acessar e atribuir nomes para elementos de tupla, conforme mostrado no código a seguir.
let print tuple1 =
match tuple1 with
| (a, b) -> printfn "Pair %A %A" a b
Você também pode desconstruir uma tupla por meio da correspondência de padrões fora de uma match
expressão por meio let
da ligação:
let (a, b) = (1, 2)
// Or as a struct
let struct (c, d) = struct (1, 2)
Ou você pode combinar padrões em tuplas como entradas para funções:
let getDistance ((x1,y1): float*float) ((x2,y2): float*float) =
// Note the ability to work on individual elements
(x1*x2 - y1*y2)
|> abs
|> sqrt
Se você precisar de apenas um elemento da tupla, o caractere curinga (o sublinhado) pode ser usado para evitar a criação de um novo nome para um valor que você não precisa.
let (a, _) = (1, 2)
Copiar elementos de uma tupla de referência para uma tupla struct também é simples:
// Create a reference tuple
let (a, b) = (1, 2)
// Construct a struct tuple from it
let struct (c, d) = struct (a, b)
As funções fst
e snd
(apenas tuplas de referência) retornam o primeiro e o segundo elementos de uma tupla, respectivamente.
let c = fst (1, 2)
let d = snd (1, 2)
Não há nenhuma função interna que retorna o terceiro elemento de um triplo, mas você pode facilmente escrever um da seguinte maneira.
let third (_, _, c) = c
Geralmente, é melhor usar a correspondência de padrões para acessar elementos de tupla individuais.
Usando Tuples
As tuplas fornecem uma maneira conveniente de retornar vários valores de uma função, como mostrado no exemplo a seguir. Este exemplo executa a divisão inteira e retorna o resultado arredondado da operação como um primeiro membro de um par de tuplas e o restante como um segundo membro do par.
let divRem a b =
let x = a / b
let y = a % b
(x, y)
Tuplas também podem ser usadas como argumentos de função quando você deseja evitar o currying implícito de argumentos de função que é implícito pela sintaxe de função usual.
let sumNoCurry (a, b) = a + b
A sintaxe usual para definir a função let sum a b = a + b
permite definir uma função que é a aplicação parcial do primeiro argumento da função, conforme mostrado no código a seguir.
let sum a b = a + b
let addTen = sum 10
let result = addTen 95
// Result is 105.
Usar uma tupla como parâmetro desativa o currying. Para obter mais informações, consulte "Aplicação parcial de argumentos" em Funções.
Nomes dos tipos de tupla
Quando você escreve o nome de um tipo que é uma tupla, você usa o *
símbolo para separar elementos. Para uma tupla que consiste em um int
, a float
, e um string
, como (10, 10.0, "ten")
, o tipo seria escrito da seguinte forma.
int * float * string
Observe que os parênteses externos são obrigatórios ao criar um alias de tipo para um tipo de tupla struct.
type TupleAlias = string * float
type StructTupleAlias = (struct (string * float))
Interoperação com Tuplas C#
Tuplas em C# são structs, e são equivalentes a struct tuplas em F#. Se você precisar interoperar com C#, você deve usar tuplas struct.
Isso é fácil de fazer. Por exemplo, imagine que você tem que passar uma tupla para uma classe C# e depois consumir seu resultado, que também é uma tupla:
namespace CSharpTupleInterop
{
public static class Example
{
public static (int, int) AddOneToXAndY((int x, int y) a) =>
(a.x + 1, a.y + 1);
}
}
Em seu código F#, você pode passar uma tupla struct como parâmetro e consumir o resultado como uma tupla struct.
open TupleInterop
let struct (newX, newY) = Example.AddOneToXAndY(struct (1, 2))
// newX is now 2, and newY is now 3
Conversão entre Tuplas de Referência e Tuplas de Estrutura
Como as Tuplas de Referência e as Tuplas de Estrutura têm uma representação subjacente completamente diferente, elas não são implicitamente conversíveis. Ou seja, códigos como os seguintes não serão compilados:
// 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
Você deve combinar padrões em uma tupla e construir a outra com as partes constituintes. Por exemplo:
// 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)
Forma Compilada de Tuplas de Referência
Esta seção explica a forma das tuplas quando elas são compiladas. As informações aqui não precisam ser lidas, a menos que você esteja direcionando o .NET Framework 3.5 ou inferior.
Tuplas são compiladas em objetos de um dos vários tipos genéricos, todos nomeados System.Tuple
, que estão sobrecarregados na aridade, ou número de parâmetros de tipo. Os tipos de tupla aparecem neste formulário quando você os visualiza de outra linguagem, como C# ou Visual Basic, ou quando você está usando uma ferramenta que não está ciente de construções F#. Os Tuple
tipos foram introduzidos no .NET Framework 4. Se você estiver direcionando uma versão anterior do .NET Framework, o compilador usa versões da System.Tuple
versão 2.0 da biblioteca principal do F#. Os tipos nesta biblioteca são usados apenas para aplicativos destinados às versões 2.0, 3.0 e 3.5 do .NET Framework. O encaminhamento de tipos é usado para garantir a compatibilidade binária entre os componentes F# do .NET Framework 2.0 e do .NET Framework 4.
Forma compilada de tuplas struct
As tuplas struct (por exemplo, struct (x, y)
), são fundamentalmente diferentes das tuplas de referência. Eles são compilados no ValueTuple tipo, sobrecarregado pela aridade, ou o número de parâmetros de tipo. Eles são equivalentes a Tuplas C# e Tuplas Visual Basic e interoperam bidirecionalmente.