Funções variantes no Go

fade by clockbirds



A equipe Mail.ru Cloud Solutions traduziu um artigo sobre funções variáveis ​​no Go. Seu autor explica como as funções variadas diferem das funções comuns e como criá-las.



O que é uma função variada



Uma função é um trecho de código projetado para realizar uma tarefa específica. A função recebe um ou mais argumentos e retorna um ou mais resultados.



As funções variantes são iguais às funções regulares, mas podem receber um número infinito ou variável de argumentos.



func f(elem ...Type)


É assim que se parece a sintaxe típica da função variável. O operador ..., também chamado de operador de boxing, diz a Go para armazenar todos os argumentos de tipo Typeem um parâmetro elem. Em outras palavras, Go cria uma variável elemcom um tipo []Type, ou seja, uma fatia. E todos os argumentos passados ​​para a função são armazenados na fatia elem.



Vamos ver um exemplo de função append().



append([]Type, args, arg2, argsN)


A função appendespera que o primeiro argumento seja uma fatia do tipo Type, seguida por um número arbitrário de argumentos. Mas como você adiciona uma fatia s2a uma fatia s1?



Da definição da função, append()segue-se que não podemos passar duas fatias para ela - há Typeapenas um argumento de tipo . Portanto, usamos o operador unboxing ...para descompactar a fatia em uma série de argumentos. Eles podem então ser passados ​​para a função append.



append(s1, s2...)


...denotam o operador de embalagem e o operador de desembalagem. O operador de unboxing sempre aparece após o nome da variável.



Em nosso exemplo, as fatias s1e s2o mesmo tipo. Normalmente conhecemos os parâmetros de uma função e o número de argumentos que ela leva. Como uma função acceptsabe quantos parâmetros foram passados ​​para ela?



Se você observar a declaração da função append, poderá ver a expressão elems ...Type. Ele compacta todos os argumentos, começando com o segundo, em uma fatia elems.



func append(slice []Type, elems ...Type) []Type


Apenas o último argumento em uma declaração de função pode ser variável.



Portanto, o primeiro argumento da função appendé apenas uma fatia, uma vez que é definida como uma fatia. Todos os argumentos subsequentes são compactados em um argumento denominado elems.



Agora vamos ver como criar sua própria função variável.



Como criar uma função variada



Conforme mencionado acima, uma função variável é uma função regular que recebe um número variável de argumentos. Para fazer isso, você precisa usar o operador de boxe ...Type.



Vamos escrever uma função getMultiplescom um primeiro argumento de factortipo int(fator de multiplicação) e um número variável de argumentos de tipo adicionais int. Eles serão embalados em uma fatia args.



Use para makecriar uma fatia vazia, é do mesmo tamanho que a fatia args. Usando um loop for range, multiplique os elementos da fatia argspor factor. Colocamos o resultado em uma nova fatia vazia multiples, que retornaremos como resultado da função.



func getMultiples(factor int, args ...int) []int {
	multiples := make([]int, len(args))
	for index, val := range args {
		multiples[index] = val * factor
	}
	return multiples
}


Esta é uma função muito simples, aplique-a dentro de um bloco main().



func main() {
	s := []int{10, 20, 30}
	mult1 := getMultiples(2, s...)
	mult2 := getMultiples(3, 1, 2, 3, 4)
	fmt.Println(mult1)
	fmt.Println(mult2)
}




https://play.go.org/p/BgU6H9orhrn



O que acontece se, no exemplo acima, você passar a fatia s para a funçãogetMultiplescomo o segundo argumento? O compilador relatará um erro:getMultiplesele não pode ser usados (type [] int)como um tipoem um argumentoint. Isso ocorre porque a fatia tem um tipo que[]int, getMultiplesespera parâmetrosint.



Como uma fatia é passada para uma função variável



Slice é uma referência a um array. Então, o que acontece quando você passa uma fatia para uma função variadic usando o operador unboxing? O Go cria uma nova fatia argsou usa uma fatia antiga s?



Como não temos ferramentas de comparação args == s, precisamos alterar a fatia args. Então, descobrimos se a fatia original foi alterada s.





https://play.go.org/p/fbNgVGu6JZO



No exemplo acima, mudamos ligeiramente a função getMultiples. E em vez de criar uma nova fatia, atribuímos os resultados do cálculo aos elementos da fatia args, substituindo os elementos de entrada pelos elementos multiplicados.



Como resultado, vemos que os valores da fatia originalsmudou. Se você passar argumentos para a função variadic por meio do operador unboxing, Go usará referências ao array de dados subjacente ao original para criar uma nova fatia. Tenha cuidado para não cometer erros, caso contrário, os dados originais serão alterados como resultado dos cálculos.



Boa sorte!



O que mais ler:



  1. Go e caches de CPU
  2. Por que um desenvolvedor de back-end deve aprender a linguagem de programação Go
  3. Nosso canal de telegramas sobre transformação digital



All Articles