One place for hosting & domains

      Como definir e chamar funções em Go


      Introdução

      Uma função é uma seção do código que, uma vez definida, pode ser reutilizada. As funções são usadas para deixar seu código mais fácil de entender: o código é dividido em tarefas menores e compreensíveis, que podem ser usadas mais de uma vez ao longo do programa.

      O Go vem com uma biblioteca padrão poderosa que possui várias funções predefinidas. As funções do pacote fmt, com as quais provavelmente você já está familiarizado, são:

      • fmt.Println() – que imprimirá objetos para a saída padrão (provavelmente o seu terminal).
      • fmt.Printf() – que permite que você formate seu resultado impresso.

      Os nomes das funções incluem parênteses e podem incluir parâmetros.

      Neste tutorial, vamos explicaremos sobre como definir suas próprias funções para usar em seus projetos de código.

      Definindo uma função

      Vamos começar a transformar o programa clássico “Hello, World!” em uma função.

      Criaremos um novo arquivo de texto em nosso editor de textos preferido e chamaremos o programa hello.go. Então, vamos definir a função.

      Uma função é definida usando a palavra-chave func. Depois dessa palavra-chave vem um nome de sua escolha e um conjunto de parênteses que possui quaisquer parâmetros que a função receberá (elas podem ficar vazias). As linhas de código da função ficam entre chaves {}.

      Neste caso, vamos definir uma função chamada hello():

      hello.go

      func hello() {}
      

      Isso define a instrução inicial para a criação de uma função.

      A partir daqui, adicionaremos uma segunda linha para fornecer as instruções para o que a função faz. Neste caso, vamos imprimir Hello, World! para o console:

      hello.go

      func hello() {
          fmt.Println("Hello, World!")
      }
      

      Nossa função agora está totalmente definida; porém, se executarmos o programa neste ponto, nada acontecerá, pois não chamamos a função.

      Assim, dentro do nosso bloco de funções main(), vamos chamar a função com hello():

      hello.go

      package main
      
      import "fmt"
      
      func main() {
          hello()
      }
      
      func hello() {
          fmt.Println("Hello, World!")
      }
      

      Agora, vamos executar o programa:

      Você receberá o seguinte resultado:

      Output

      Hello, World!

      Note que também introduzimos uma função chamada main(). A função main() é uma função especial que diz ao compilador que é aqui que o programa deve iniciar. Para qualquer programa que você queira que seja executável (um programa que pode ser executado a partir da linha de comando), você vai precisar de uma função main(). A função main() deve aparecer apenas uma vez, estar no pacote main() e não deve receber nem retornar argumentos. Isso permite a execução do programa em qualquer programa em Go. De acordo com o exemplo a seguir:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          fmt.Println("this is the main section of the program")
      }
      

      As funções podem ficar mais complicadas do que a função hello() que definimos. Podemos usar loops for, instruções condicionais e mais, dentro do nosso bloco de função.

      Por exemplo, a função a seguir usa uma instrução condicional para verificar se a entrada da variável name contém uma vogal; depois, ela usa um loop for para iterar nas letras da string name.

      names.go

      package main
      
      import (
          "fmt"
          "strings"
      )
      
      func main() {
          names()
      }
      
      func names() {
          fmt.Println("Enter your name:")
      
          var name string
          fmt.Scanln(&name)
          // Check whether name has a vowel
          for _, v := range strings.ToLower(name) {
              if v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u' {
                  fmt.Println("Your name contains a vowel.")
                  return
              }
          }
          fmt.Println("Your name does not contain a vowel.")
      }
      

      A função name() que definimos aqui define uma variável name com entrada e, em seguida, define uma instrução condicional dentro de um loop for. Isso mostra como o código pode ser organizado dentro de uma definição de função. No entanto, dependendo do que pretendemos com nosso programa e como queremos configurar nosso código, podemos querer definir a instrução condicional e o loop for como duas funções separadas.

      Definir funções dentro de um programa torna o nosso código modular e reutilizável para que possamos chamar as mesmas funções sem reescrevê-las.

      Até agora, examinamos funções com parênteses vazios, que não recebem argumentos, mas podemos definir parâmetros nas definições da função dentro de seus parênteses.

      Um parâmetro é uma entidade nomeada na definição de uma função, que especifica um argumento que a função pode aceitar. Na linguagem Go, você deve especificar o tipo de dados de cada parâmetro.

      Vamos criar um programa que repete uma palavra pelo número de vezes especificado. O programa aceitará um parâmetro de string, chamado word e um parâmetro de int chamado reps em relação ao número de vezes a se repetir a palavra.

      repeat.go

      package main
      
      import "fmt"
      
      func main() {
          repeat("Sammy", 5)
      }
      
      func repeat(word string, reps int) {
          for i := 0; i < reps; i++ {
              fmt.Print(word)
          }
      }
      

      Enviamos o valor Sammy para o parâmetro word e 5 para o parâmetro reps. Esses valores correspondem a cada parâmetro na ordem que eles foram dados. A função repeat tem um loop for que irá iterar pelo número de vezes especificado pelo parâmetro reps. Para cada iteração, o valor do parâmetro word será impresso.

      Aqui está o resultado do programa:

      Output

      SammySammySammySammySammy

      Se você tiver um conjunto de parâmetros - todos com o mesmo valor, você pode omitir, especificando o tipo a cada vez. Vamos criar um pequeno programa que recebe os parâmetros x, y e z que estão todos com valores int. Criaremos uma função que adiciona os parâmetros juntos, em configurações diferentes. As somas deles serão impressos pela função. Então, vamos chamar a função e enviar números para a função.

      add_numbers.go

      package main
      
      import "fmt"
      
      func main() {
          addNumbers(1, 2, 3)
      }
      
      func addNumbers(x, y, z int) {
          a := x + y
          b := x + z
          c := y + z
          fmt.Println(a, b, c)
      }
      

      Ao criarmos a assinatura da função para addNumbers, não precisamos especificar o tipo a cada vez, apenas no final.

      Enviamos o número 1 para o parâmetro x, o 2 para o parâmetro y e o 3 para o parâmetro z. Esses valores correspondem a cada parâmetro na ordem em que eles são dados.

      O programa está fazendo a seguinte operação matemática, com base nos valores que enviamos para os parâmetros:

      a = 1 + 2
      b = 1 + 3
      c = 2 + 3
      

      A função também imprime a, b e c e, com base nessa operação matemática, esperamos que a seja igual a 3, b igual a 4 e c igual a 5. Vamos executar o programa:

      Output

      3 4 5

      Quando enviamos 1, 2 e 3 como parâmetros para a função addNumbers(), recebemos o resultado esperado.

      Os parâmetros são argumentos, normalmente definidos como variáveis nas definições da função. Ao executar o método, você pode atribuir valores aos parâmetros, enviando os argumentos para a função.

      Retornando um valor

      Você pode enviar um valor de parâmetro para uma função e uma função também pode produzir um valor.

      Uma função pode produzir um valor com a instrução return, o qual sairá de uma função e enviará, opcionalmente, uma expressão de volta para o chamador. O tipo de dados retornados também deve ser especificado.

      Até agora, usamos a instrução fmt.Println() em vez da instrução return em nossas funções. Vamos criar um programa que, em vez de imprimir, retornará uma variável.

      Em um novo arquivo de texto chamado double.go, vamos criar um programa que duplica o parâmetro x e retorna a variável y. Nós emitimos uma chamada para imprimir a variável result, que é formada por meio da execução da função double() com um 3 enviado para ela:

      double.go

      package main
      
      import "fmt"
      
      func main() {
          result := double(3)
          fmt.Println(result)
      }
      
      func double(x int) int {
          y := x * 2
          return y
      }
      
      

      Podemos executar o programa e ver o resultado:

      Output

      6

      O número inteiro 6 é retornado como o resultado, que se trata do que esperávamos da multiplicação de 3 por 2.

      Se uma função especifica um retorno, você deve fornecer um retorno como parte do código. Se não fizer isso, receberá um erro de compilação.

      Podemos demonstrar isso, comentando a linha (do código) com a instrução de retorno:

      double.go

      package main
      
      import "fmt"
      
      func main() {
          result := double(3)
          fmt.Println(result)
      }
      
      func double(x int) int {
          y := x * 2
          // return y
      }
      
      

      Agora, vamos executar o programa novamente:

      Output

      ./double.go:13:1: missing return at end of function

      Sem usar a instrução return aqui, o programa não pode compilar.

      As funções saem imediatamente quando atingem a instrução return, mesmo se elas não estiverem no final da função:

      return_loop.go

      package main
      
      import "fmt"
      
      func main() {
          loopFive()
      }
      
      func loopFive() {
          for i := 0; i < 25; i++ {
              fmt.Print(i)
              if i == 5 {
                  // Stop function at i == 5
                  return
              }
          }
          fmt.Println("This line will not execute.")
      }
      

      Aqui, iteramos um loop for e dizemos ao loop para executar 25 iterações. No entanto, dentro do loop for, temos uma instrução condicional if que verifica se o valor de i é igual a 5. Se for, emitimos uma instrução return. Como estamos na função loopFive, qualquer return em qualquer ponto na função sairá da função. Consequentemente, nunca chegaremos à última linha dessa função para imprimir a instrução This line will not execute. (Esta linha não será executada.).

      Usar a instrução return dentro do loop for encerra a função, de modo que a linha que está fora do loop não será executada. Se, em vez disso, tivéssemos usado uma instrução break, apenas o loop teria saído naquele momento e a última linha da fmt.Println() seria executada.

      A instrução return sai de uma função e pode retornar um valor se especificado na assinatura da função.

      Retornando valores múltiplos

      Mais de um valor retornado pode ser especificado para uma função. Vamos examinar o programa repeat.go e fazer com que ele retorne dois valores. O primeiro será o valor repetido e o segundo será um erro se o parâmetro reps não for um valor maior que 0:

      repeat.go

      package main
      
      import "fmt"
      
      func main() {
          val, err := repeat("Sammy", -1)
          if err != nil {
              fmt.Println(err)
              return
          }
          fmt.Println(val)
      }
      
      func repeat(word string, reps int) (string, error) {
          if reps <= 0 {
              return "", fmt.Errorf("invalid value of %d provided for reps. value must be greater than 0.", reps)
          }
          var value string
          for i := 0; i < reps; i++ {
              value = value + word
          }
          return value, nil
      }
      

      A primeira coisa que a função repeat faz é verificar se o argumento reps é um valor válido. Qualquer valor que não seja maior do que 0 causará um erro. Como enviamos o valor de -1, essa ramificação do código será executada. Note que, quando retornamos da função, precisamos fornecer os valores retornados string e error. Como os argumentos fornecidos resultaram em um erro, vamos enviar uma string em branco de volta para o primeiro valor retornado e o erro para o segundo valor retornado.

      Na função main() podemos receber ambos valores retornados, declarando duas novas variáveis, value e err. Como pode haver um erro no retorno, vamos verificar se recebemos um erro antes de continuar com nosso programa. Neste exemplo, recebemos um erro. Nós imprimimos o erro e o return da função main() para sair do programa.

      Se não houvesse um erro, imprimiríamos o valor retornado da função.

      Nota: é considerada uma melhor prática retornar apenas dois ou três valores. Além disso, você deve sempre retornar todos os erros como o último valor de retorno de uma função.

      Executar o programa resultará no seguinte resultado:

      Output

      invalid value of -1 provided for reps. value must be greater than 0.

      Nesta seção, analisamos como podemos usar a instrução return para retornar valores múltiplos de uma função.

      Conclusão

      As funções são blocos de código de instruções que realizam ações dentro de um programa, ajudando a tornar o nosso código reutilizável e modular.

      Para aprender mais sobre como tornar seu código mais modular, leia o nosso guia sobre Como escrever pacotes em Go.



      Source link


      Leave a Comment