F# Delegados

Neste artigo, você explorará o conceito de delegados do F# e aprenderá como usá-los para criar uma funcionalidade mais avançada e flexível.

Os delegados do F# permitem que você defina funções como valores de primeira classe, o que significa que você pode trabalhar com eles como se fossem valores de primeira classe.

Uma função é tratada como qualquer outro tipo de dado, seja um inteiro, uma string ou uma matriz, sendo tratada como um valor. Isso significa que uma função pode ser passada como argumento para outra função, retornada de outra função ou armazenada em uma estrutura de dados.

Usar o delegado F# significa encapsular um método ou função em um valor que pode ser passado ou invocado posteriormente.

O mecanismo de delegação é uma maneira flexível e poderosa de criar funções de ordem superior, geralmente chamadas de funções multifuncionais porque podem ser entradas ou saídas de outras funções.



Declarando delegados em F#

As declarações de delegado definem quais métodos podem ser referenciados pelo delegado e quais métodos podem ser chamados pelo delegado.

Existe a possibilidade de um delegado se referir a um método cuja assinatura tenha a mesma do próprio delegado.

As declarações de delegado têm a seguinte sintaxe:

type delegate-typename = delegate of type1 -> type2

Abaixo está um exemplo de declaração de delegado:

// Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int * int) -> int

// Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int

Existem dois delegados que podem ser usados ​​para se referir a qualquer método com dois parâmetros int e que retorna uma variável de tipo int .

É assim que a sintaxe se parece:

  • type1 é uma representação do(s) tipo(s) de argumento.
  • type2 é uma representação do tipo de retorno.

Observação:

  • Há uma conversão automática entre os tipos de argumento.
  • O delegado pode ser anexado ao valor da função, bem como aos métodos estáticos ou de instância na função.
  • O valor da função AF# pode ser passado diretamente para um construtor delegado como um argumento.
  • Para métodos estáticos, o delegado é chamado referenciando o nome da classe e o nome do método na chamada do delegado. Um método de instância refere-se à instância do objeto e ao método do objeto e é referido como seu nome.
  • A chamada da função encapsulada é realizada por meio do método Invoke do tipo delegado.
  • Além disso, quando o nome do método Invoke é referenciado sem os parênteses, os delegados também podem ser passados ​​como valores de função.

Aqui está um exemplo do delegado que a Microsoft fornece neste exemplo, para que possamos entender melhor:

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
type Test() =
static member add(a : int, b : int) =
a + b
static member mul (a : int) (b : int) =
a * b
member x.Add(a : int, b : int) =
a + b
member x.Mul (a : int) (b : int) =
a * b
// Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int * int) -> int
// Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int
let InvokeDelegate1 (dlg: Delegate1) (a: int) (b: int) =
dlg.Invoke(a, b)
let InvokeDelegate2 (dlg: Delegate2) (a: int) (b: int) =
dlg.Invoke(a, b)
// For static methods, use the class name, the dot operator, and the
// name of the static method.
let del1 : Delegate1 = new Delegate1( Test.add )
let del2 : Delegate2 = new Delegate2( Test.mul )
let test = Test()
// For instance methods, use the instance value name, the dot operator, and the instance method name.
let del3 : Delegate1 = new Delegate1( test.Add )
let del4 : Delegate2 = new Delegate2( test.Mul )
for (a, b) in [ (50, 100); (20, 5) ] do
printfn "%d + %d = %d" a b (InvokeDelegate1 del1 a b)
printfn "%d * %d = %d" a b (InvokeDelegate2 del2 a b)
printfn "%d + %d = %d" a b (InvokeDelegate1 del3 a b)
printfn "%d * %d = %d" a b (InvokeDelegate2 del4 a b)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

E a saída será como:

50 + 100 = 150
50 * 100 = 5000
50 + 100 = 150
50 * 100 = 5000
20 + 5 = 25
20 * 5 = 100
20 + 5 = 25
20 * 5 = 100

Exemplo de Explicação

Escrevemos este código F# que define uma classe Test com métodos estáticos e de instância e delegados para invocar esses métodos. Aqui está um detalhamento do código:

  • A classe Test contém os métodos estáticos add e mul para adição e multiplicação de dois inteiros, respectivamente. Além disso, ele possui métodos de instância Add e Mul que executam as mesmas operações, mas são chamados em uma instância da classe Test.
  • Definimos dois tipos de delegado chamados Delegate1 e Delegate2 , que especificam as assinaturas de função que podem representar. Delegate1 recebe uma tupla de dois inteiros como argumentos e retorna um inteiro, enquanto Delegate2 recebe dois argumentos inteiros e retorna um inteiro.
  • Escrevemos duas funções , InvokeDelegate1 e InvokeDelegate2 , que recebem instâncias delegadas junto com dois argumentos inteiros e, em seguida, invocam as instâncias delegadas usando o método Invoke com esses argumentos inteiros.
  • Criamos instâncias delegadas del1, del2, del3 e del4, que representam métodos estáticos e de instância da classe Test usando a palavra-chave new.
  • Também criamos uma instância da classe Test chamada test.
  • Finalmente, usamos um loop for para iterar sobre uma lista de tuplas contendo pares (a, b). Chamamos as funções InvokeDelegate1 e InvokeDelegate2 com delegados del1 , del2 , del3 e del4 , passando a e b como argumentos. Imprimimos os resultados dessas invocações de método usando a instrução printfn .

Conclusão

Delegados são um poderoso recurso de linguagem no F# que permite representar funções como dados. Eles são particularmente úteis na manipulação de eventos e na programação funcional, onde as funções de ordem superior podem receber delegados como argumentos. Entender os delegados em F# ajudará você a escrever um código mais expressivo e funcional.

Nós valorizamos o seu feedback.
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0

Assine a nossa newsletter
Digite seu e-mail para receber um resumo semanal de nossos melhores posts. Saber mais!
ícone