Exemplos de Genéricos Golang

Exemplos De Genericos Golang



O recurso genérico do Golang possibilita a criação de um código reutilizável que é seguro e compatível com uma ampla variedade de tipos. Felizmente, a adição de genéricos ao Go abre novos caminhos para reutilização e flexibilidade de código. A versão mais recente do Golang traz consigo o tão esperado suporte para genéricos.

Mais importante, os genéricos mantêm a forte segurança de tipo do Go, que permite a verificação estática de tipo em tempo de compilação e garante a correção do tipo. Eles fornecem um tratamento de erro padronizado dentro do código genérico que melhora a clareza e a capacidade de manutenção. Além disso, eles fornecem um tratamento de erros padronizado dentro do código genérico, o que melhora a clareza e a facilidade de manutenção. Nesta postagem, examinaremos os vários exemplos e aplicativos genéricos Go do mundo real.

Exemplo 1: Usando a Função Genérica Golang

Um dos principais casos de uso de genéricos é a criação de funções que podem operar em tipos distintos. Aqui, vamos com um dos exemplos onde a função circunferência genérica é usada.







pacote principal
importar 'fmt'
função circunferência [ r int | float32 ]( raio r ) {
c := 3 * 2 * raio
fmt . Println ( 'A circunferência genérica é: ' , c )
}
função principal () {
era r1 int = 7
era r2 float32 = 7 . 5
circunferência ( r1 )
circunferência ( r2 )
}

No início do código anterior, a linha importa o pacote “fmt” que fornece funções para E/S formatadas, incluindo a impressão da saída no console. Em seguida, definimos uma função genérica chamada “circunferência” que recebe um parâmetro raio de um tipo genérico “r” que pode ser um “int” ou um “float32”. Dentro da função, calcula a circunferência multiplicando o raio pelo valor constante de “3” e depois multiplicando por “2”. Finalmente, imprime a circunferência calculada usando “fmt.Println”.



Em seguida, temos a função principal onde duas variáveis, r1 e r2, são declaradas e atribuídas com os valores de 7 e 7,5, respectivamente. Depois disso, a função “circunferência” é invocada duas vezes, passando r1 e r2 como argumentos.



A saída exibe o cálculo imprimindo as circunferências dos círculos no seguinte:





Exemplo 2: usando a interface genérica Golang

Além disso, os genéricos Golang nos auxiliam com suas interfaces. As interfaces em Go são uma ferramenta vital para facilitar a reutilização e o polimorfismo do código. Ao permitir que funcionem com muitos tipos, os genéricos aumentam o poder das interfaces. A seguir está o código-fonte da interface genérica Golang:



pacote principal
importar 'fmt'
tipo EmpAge interface {
int64 | int32 | float32 | float64
}
função newGenericFunc [ idade idade ]( emp_idade idade ) {
val := int ( emp_Idade ) + 1
fmt . Println ( val )
}
função principal () {
fmt . Println ( 'Idade dos Funcionários' )
era idade1 int64 = 24
era Age2 float64 = 25 . 5
newGenericFunc ( idade1 )
newGenericFunc ( Age2 )
}

No código-fonte anterior, definimos uma interface chamada “EmpAge” que especifica os tipos possíveis para a idade de um funcionário. A interface inclui os tipos int64, int32, float32 e float64. Essa interface permite que a função “genérica” aceite qualquer um desses tipos como argumento. Depois disso, empregamos uma função genérica chamada newGenericFunc que recebe o parâmetro emp_Age de um tipo genérico de age que pode ser qualquer tipo que satisfaça a interface EmpAge. Dentro da função, ele converte o emp_Age em um int e o incrementa em 1, conforme mostrado.

Em seguida, declaramos as duas variáveis, Age1 e Age2, e atribuímos os valores de 24 e 25,5, respectivamente, na função principal. Posteriormente, Age1 e Age2 são passados ​​como parâmetros para a função newGenericFunc que é executada duas vezes. Com isso, as idades são elevadas em 1 e geram os valores atualizados.

A saída produzida a seguir são as idades da função genérica que utiliza a interface:

Exemplo 3: usando a estrutura de dados genérica Golang

Além disso, os genéricos Go também nos dão a capacidade de construir as estruturas de dados genéricos, como pilhas, filas e listas encadeadas. Considere a implementação da pilha genérica a seguir:

importar 'fmt'
tipo Pilha [ qualquer um ] [] T
função ( st * Pilha [ T ]) Empurrar ( item T ) {
st = acrescentar ( * st , item )
}
função ( st * Pilha [ T ]) pop () T {
se apenas ( * st ) == 0 {
pânico ( 'Nada na pilha' )
}
índice := apenas ( * st ) - 1
item := ( * st )[ índice ]
* st = ( * st )[: índice ]
retornar item
}
função principal () {
pilha := novo ( Pilha [ int ])
pilha . Empurrar ( 1 )
pilha . Empurrar ( 2 )
pilha . Empurrar ( 3 )
fmt . Println ( pilha . pop ())
fmt . Println ( pilha . pop ())
fmt . Println ( pilha . pop ())
}

No código anterior, é definido um tipo genérico intitulado “Stack” que representa a pilha. O marcador de posição “T” permite que a pilha contenha os elementos de qualquer tipo. O tipo “Stack” é implementado como uma fatia de elementos do tipo “T”. Aqui, duas funções são implantadas para o tipo “Stack”: “Push” e “Pop”. A função Push() é responsável por adicionar os elementos à pilha. Ele pega um item de argumento do tipo “T” e o anexa à fatia subjacente usando a função append().

Embora a função Pop() pegue o componente inicial da pilha e o retorne, ela primeiro determina se a pilha está vazia avaliando o tamanho da fatia subjacente. Uma notificação de erro é enviada se a pilha parecer estar vazia, o que causa pânico. Caso contrário, ele recupera o último elemento da fatia, remove-o da pilha dividindo a fatia até o penúltimo elemento e retorna o item removido.

Em seguida, a nova pilha de inteiros é criada usando a sintaxe Stack[int] dentro da função principal desse código. Depois disso, o método “Push” é chamado três vezes para adicionar os inteiros 1, 2 e 3 à pilha. No entanto, o método “Pop” é chamado três vezes posteriormente para recuperar e imprimir os elementos da pilha.

A saída a seguir indica que os elementos são removidos da pilha na ordem inversa:

Exemplo 4: usando as restrições genéricas de Golang

Go também oferece restrições personalizadas que permitem uma grande flexibilidade e definem requisitos específicos para construções genéricas com base nas necessidades de sua aplicação. O código das restrições genéricas personalizadas é fornecido a seguir para demonstração:

pacote principal
importar 'fmt'
tipo numéricos interface {
int64 | float64
}
função principal () {
FloatValue := [] float64 { 2 . 0 , 4 . 0 , 6 . 0 , 8 . 0 , 10 . 0 }
Valor inteiro := [] int64 { 2 , 4 , 6 , 8 , 10 }
soma1 := somagenérica ( FloatValue )
soma2 := somagenérica ( Valor inteiro
fmt . Println ( 'Soma de float64 :' , soma1 )
fmt . Println ( 'Soma de int64:' , soma2 )

}
função somagenérica [ n Numéricos ]( números [] n ) n {
era eu sou n
para _ , Num := faixa números {
soma += Num
}
retornar soma
}

No código fonte anterior, definimos a interface Numerics com o método “Sum”. Em seguida, criamos dois tipos personalizados, “FloatValue” e “IntegerValue”, que implementam a interface Numerics fornecendo seus respectivos métodos “Sum”. A função genericSum agora pode aceitar fatias de qualquer tipo que satisfaça a interface Numerics. Dentro da função, iteramos sobre os elementos e chamamos o método “Sum” para calcular a soma. Finalmente, na função principal, criamos as fatias de FloatValue e IntegerValue e as passamos para a função genericSum() que calcula corretamente a soma dos elementos em cada fatia.

A saída esperada agora está visível na tela a seguir:

Conclusão

Exploramos alguns exemplos práticos de genéricos do Go que incluem a criação de uma estrutura de dados genérica e uma função genérica, definindo uma interface genérica e usando a restrição de tipo personalizado. Esses exemplos demonstram o poder e a flexibilidade que os genéricos trazem para a linguagem de programação Go. Observe que a geração de código genérico durante a compilação garante o tamanho binário e os tempos de compilação eficientes.