In this section, we are going to talk about control statements and function operations in Go.
Nesta seção nós vamos falar sobre declarações de controle e operações de funções em Go.
## Control statement
## Declarações de Controle
The greatest invention in programming is flow control. Because of them, you are able to use simple control statements that can be used to represent complex logic. There are three categories of flow control: conditional, cycle control and unconditional jump.
A maior invenção na programação é o controle de fluxo. Por causa dele, você é capaz de utilizar declarações de controle simples que podem ser usadas para representar lógicas complexas. Existem três categorias de controle de fluxo: condicional, controle de ciclo e salto incondicional.
### if
`if`will most likely be the most common keyword in your programs. If it meets the conditions, then it does something and it does something else if not.
`if`provavelmente será a palavra-chave mais utilizada nos seus programas. Se ele atende as condições, então ele faz alguma coisa e caso contrário faz alguma outra coisa.
`if`doesn't need parentheses in Go.
`if`não precisa de parênteses em Go.
if x > 10 {
fmt.Println("x is greater than 10")
@@ -18,19 +18,19 @@ The greatest invention in programming is flow control. Because of them, you are
fmt.Println("x is less than or equal to 10")
}
The most useful thing concerning`if`in Go is that it can have one initialization statement before the conditional statement. The scope of the variables defined in this initialization statement are only available inside the block of the defining`if`.
A coisa mais útil sobre o`if`em Go é que ele pode ter uma instrução de inicialização antes da instrução condicional. O escopo das variáveis definidas nesta instrução de inicialização só estão disponíveis dentro do bloco de definição do`if`.
// initialize x, then check if x greater than
// inicializa x e então confere se x é maior que 10
if x := computedValue(); x > 10 {
fmt.Println("x is greater than 10")
} else {
fmt.Println("x is less than 10")
}
// the following code will not compile
// o código seguinte não compilará
fmt.Println(x)
Use if-else for multiple conditions.
Use if-else para múltiplas condições.
if integer == 3 {
fmt.Println("The integer is equal to 3")
@@ -42,29 +42,29 @@ Use if-else for multiple conditions.
### goto
Go has a `goto` keyword, but be careful when you use it. `goto` reroutes the control flow to a previously defined `label` within the body of same code block.
Go possui uma palavra-chave chamada `goto`, mas cuidado ao utilizar ela. `goto` reencaminha o fluxo de controle para um `label` definido anteriormente dentro do mesmo blocode código.
func myFunc() {
i := 0
Here: // label ends with ":"
Here: // label termina com ":"
fmt.Println(i)
i++
goto Here // jump to label "Here"
goto Here // pule para o label "Here"
}
The label name is case sensitive.
O nome do label é case sensitive.
### for
`for`is the most powerful control logic in Go. It can read data in loops and iterative operations, just like`while`.
`for`é a lógica de controle mais poderosa em Go. Ele pode ler dados em loops e operações iterativas, assim como o`while`.
for expression1; expression2; expression3 {
//...
}
`expression1`, `expression2`and`expression3`are all expressions, where `expression1`and`expression3`are variable definitions or return values from functions, and `expression2` is a conditional statement. `expression1`will be executed once before looping, and `expression3` will be executed after each loop.
`expression1`, `expression2`e`expression3`são todas expressões, onde `expression1`e`expression3`são definições de variáveis ou atribuições, e `expression2` é uma declaração condicional. `expression1`será executada uma vez antes do loop, e `expression3` será executada depois de cada iteração do loop.
Examples are more useful than words.
Exemplos são mais úteis que palavras.
package main
import "fmt"
@@ -76,43 +76,43 @@ Examples are more useful than words.
}
fmt.Println("sum is equal to ", sum)
}
// Print:sum is equal to 45
// Mostra:sum is equal to 45
Sometimes we need multiple assignments, but Go doesn't have the `,` operator, so we use parallelassignment like`i, j = i + 1, j - 1`.
Algumas vezes nós precisamos de várias atribuições, porém Go não possui o operador `,`, então nós usamos atribuições paralelas como`i, j = i + 1, j - 1`.
We can omit`expression1`and`expression3`if they are not necessary.
Nós podemos omitir as expressões`expression1`e`expression3`se elas não forem necessárias.
sum := 1
for ; sum < 1000; {
sum += sum
}
Omit `;` as well. Feel familiar? Yes, it's identical to `while`.
Podemos omitir também o `;`. Isto lhe parece familiar? Sim, é idêntico ao `while`.
sum := 1
for sum < 1000 {
sum += sum
}
There are two important operations in loops which are`break`and`continue`. `break`jumps out of the loop, and`continue`skips the current loop and starts the next one. If you have nested loops, use `break`along with labels.
Existem duas operações importantes em loops que são`break`e`continue`. `break`"pula" fora do loop, e`continue`ignora o loop atual e inicia o próximo. Se você tiver loops aninhados use `break`juntamente com labels.
for index := 10; index>0; index-- {
if index == 5{
break // or continue
break // ou continue
}
fmt.Println(index)
}
// break prints 10、9、8、7、6
// continue prints 10、9、8、7、6、4、3、2、1
// break mostra 10、9、8、7、6
// continue mostra 10、9、8、7、6、4、3、2、1
`for`can read data from `slice`and`map`when it is used together with`range`.
`for`pode ler dados de um `slice`ou`map`quando for utilizado junto com`range`.
for k,v:=range map {
fmt.Println("map's key:",k)
fmt.Println("map's val:",v)
}
Because Go supports multi-value returns and gives compile errors when you don't use values that were defined, you may want to use`_`to discard certain return values.
Como Go suporta múltiplos valores de retorno e gera um erro de compilação caso você não use os valores que foram definidos, você pode querer utilizar`_`para descartar certos valores de retorno.
for _, v := range map{
fmt.Println("map's val:", v)
@@ -120,7 +120,7 @@ Because Go supports multi-value returns and gives compile errors when you don't
### switch
Sometimes you may find that you are using too many `if-else` statements to implement some logic, which may make it difficult to read and maintain in the future. This is the perfect time to use the `switch` statement to solve this problem.
As vezes você pode achar que está usando muitas instruções `if-else` para implementar uma lógica, o que pode dificultar a leitura e manutenção no futuro. Este é o momento perfeito para utilizar a instrução `switch` para resolver este problema.
switch sExpr {
case expr1:
@@ -133,7 +133,7 @@ Sometimes you may find that you are using too many `if-else` statements to imple
other code
}
The type of`sExpr`, `expr1`, `expr2`, and`expr3`must be the same. `switch` is very flexible. Conditions don't have to be constants and it executes from top to bottom until it matches conditions. If there is no statement after the keyword `switch`, then it matches`true`.
Os tipos de`sExpr`, `expr1`, `expr2`, e`expr3`devem ser o mesmo. `switch` é muito flexível. As condições não precisam ser constantes e são executadas de cima para baixo até que encontre uma condição válida. Se não houver nenhuma instrução após a palavra-chave `switch`, então ela corresponderá a`true`.
i := 10
switch i {
@@ -147,7 +147,7 @@ The type of `sExpr`, `expr1`, `expr2`, and `expr3` must be the same. `switch` is
fmt.Println("All I know is that i is an integer")
}
In the fifth line, we put many values in one`case`, and we don't need to add the `break` keyword at the end of `case`'s body. It will jump out of the switch body once it matched any case. If you want to continue to matching more cases, you need to use the`fallthrough` statement.
Na quinta linha, colocamos vários valores em um`case`, e não precisamos adicionar a palavra-chave `break` no final do bloco do `case`. Ele irá sair do bloco do switch quando encontrar uma condição verdadeira. Se você deseja continuar verificando mais casos, você precisará utilizar a instrução `fallthrough`.
integer := 6
switch integer {
@@ -170,39 +170,39 @@ In the fifth line, we put many values in one `case`, and we don't need to add th
fmt.Println("default case")
}
This program prints the following information.
Este programa mostra a seguinte informação.
integer <= 6
integer <= 7
integer <= 8
default case
## Functions
## Funções
Use the `func` keyword to define a function.
Use a palavra-chave `func` para definir uma função.
We can extrapolate the following information from the example above.
Nós podemos extrapolar as seguintes informações do exemplo acima.
- Use keyword`func`to define a function`funcName`.
- Functions have zero, one or more than one arguments. The argument type comes after the argument name and arguments are separated by`,`.
- Functions can return multiple values.
-There are two return values named`output1`and`output2`, you can omit their names and use their type only.
-If there is only one return value and you omitted the name, you don't need brackets for the return values.
-If the function doesn't have return values, you can omit the return parameters altogether.
-If the function has return values, you have to use the `return` statement somewhere in the body of the function.
- Use a palavra-chave`func`para definir uma função`funcName`.
- Funções tem zero, um ou mais argumentos. O tipo do argumento vem depois do nome do argumento e vários argumentos são separados por`,`.
- Funções podem retornar múltiplos valores.
-Existem dois valores de retorno com os nomes`output1`e`output2`, você pode omitir estes nomes e usar apenas os tipos deles.
-Se existe apenas um valor de retorno e você omitir o nome, você não precisa usar colchetes nos valores de retorno.
-Se a função não possui valores de retorno, você pode omitir os parâmetros de retorno completamente.
-Se a função possui valores de retorno, você precisa utilizar a instrução `return` em algum lugar no corpo da função.
Let's see one practical example. (calculate maximum value)
Vamos ver um exemplo prático. (calcular o valor máximo)
package main
import "fmt"
// return greater value between a and b
// retorna o maior valor entre a e b
func max(a, b int) int {
if a > b {
return a
@@ -215,26 +215,26 @@ Let's see one practical example. (calculate maximum value)
y := 4
z := 5
max_xy := max(x, y) // call function max(x, y)
max_xz := max(x, z) // call function max(x, z)
max_xy := max(x, y) // chama a função max(x, y)
max_xz := max(x, z) // chama a função max(x, z)
fmt.Printf("max(%d, %d) = %d\n", x, y, max_xy)
fmt.Printf("max(%d, %d) = %d\n", x, z, max_xz)
fmt.Printf("max(%d, %d) = %d\n", y, z, max(y,z)) // call function here
fmt.Printf("max(%d, %d) = %d\n", y, z, max(y,z)) // chama a função max aqui
}
In the above example, there are two arguments in the function `max`, their types are both `int` so the first type can be omitted. For instance,`a, b int`instead of`a int, b int`. The same rules apply for additional arguments. Notice here that`max`only has one return value, so we only need to write the type of its return value -this is the short form of writing it.
No exemplo acima existem dois argumentos do tipo `int` na função `max`, sendo assim o tipo do primeiro argumento pode ser omitido. Por exemplo, pode-se utilizar`a, b int`em vez de`a int, b int`. As mesmas regras se aplicam para argumentos adicionais. Observe aqui que`max`só tem um valor de retorno, então nós só precisamos escrever o tipo do valor de retorno. Esta é a forma curta de escrevê-lo.
### Multi-value return
### Múltiplos valores de retorno
One thing that Go is better at than C is that it supports multi-value returns.
Uma coisa em que Go é melhor que C é que ela suporta múltiplos valores de retorno.
We'll use the following example here.
Usaremos o seguinte exemplo.
package main
import "fmt"
// return results of A + B and A * B
// Retorna os resultados de A + B e A * B
func SumAndProduct(A, B int) (int, int) {
return A+B, A*B
}
@@ -249,7 +249,7 @@ We'll use the following example here.
fmt.Printf("%d * %d = %d\n", x, y, xTIMESy)
}
The above example returns two values without names -you have the option of naming them also. If we named the return values, we would just need to use`return`to return the values since they are initialized in the function automatically. Notice that if your functions are going to be used outside of the package, which means your function names start with a capital letter, you'd better write complete statements for `return`; it makes your code more readable.
O exemplo acima retorna dois valores sem nomes - você também tem a opção de nomeá-los se preferir. Se nomearmos os valores de retorno, poderemos utilizar apenas a instrução`return`para retornar os valores já que eles foram inicializados na função automaticamente. Observe que se suas funções forem utilizadas fora do pacote, o que significa que o nome das funções começam com uma letra maiúscula, é melhor escrever instruções completas para o `return`. Isto torna o seu código mais legível.
func SumAndProduct(A, B int) (add int, Multiplied int) {
add = A+B
@@ -257,85 +257,85 @@ The above example returns two values without names -you have the option of namin
return
}
### Variable arguments
### Argumentos variáveis
Go supports variable arguments, which means you can give an uncertain numbers of argument to functions.
Go suporta argumentos variáveis, o que significa que você pode dar um número incerto de argumentos para funções.
func myfunc(arg ...int) {}
`arg …int`tells Go that this is a function that has variable arguments. Notice that these arguments are type `int`. In the body of function, the `arg` becomes a`slice`of`int`.
A instrução `arg …int`significa que esta é uma função que possui argumentos variáveis. Observe que estes argumentos são do tipo `int`. No corpo da função o `arg` se torna um`slice`de`int`.
for _, n := range arg {
fmt.Printf("And the number is: %d\n", n)
}
### Pass by value and pointers
### Passar por valor e ponteiros
When we pass an argument to the function that was called, that function actually gets the copy of our variables so any change will not affect to the original variable.
Quando passamos um argumento para uma função que foi chamada, a função recebe na verdade uma cópia da nossa variáveis original, sendo assim, as alterações não afetarão a variável original.
Let's see one example in order to prove what i'm saying.
Vejamos um exemplo para provar o que eu estou dizendo.
package main
import "fmt"
// simple function to add 1 to a
// Função simples que adiciona 1 a variável a
func add1(a int) int {
a = a+1 // we change value of a
return a // return new value of a
a = a+1 // alteramos o valor de a
return a // retornamos o novo valor de a
}
func main() {
x := 3
fmt.Println("x = ", x) // should print "x = 3"
fmt.Println("x = ", x) // deve mostrar "x = 3"
x1 := add1(x) // call add1(x)
x1 := add1(x) // chama add1(x)
fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
fmt.Println("x = ", x) // should print "x = 3"
fmt.Println("x+1 = ", x1) // deve mostrar "x+1 = 4"
fmt.Println("x = ", x) // deve mostrar "x = 3"
}
Can you see that? Even though we called`add1`with`x`, the origin value of `x` doesn't change.
Você consegue ver isso? Mesmo que nós chamamos`add1`com`x`, o valor original de `x` não é alterado.
The reason is very simple: when we called `add1`, we gave a copy of `x` to it, not the `x` itself.
A razão é muito simples: quando chamamos `add1`, nós passamos uma cópia de `x` para a função, e não o próprio `x`.
Now you may ask how I can pass the real `x` to the function.
Agora você pode se perguntar, como eu posso passar o `x` original para a função.
We need use pointers here. We know variables are stored in memory and they have some memory addresses. So, if we want to change the value of a variable, we must change its memory address. Therefore the function `add1` has to know the memory address of `x` in order to change its value. Here we pass `&x`to the function, and change the argument's type to the pointer type`*int`. Be aware that we pass a copy of the pointer, not copy of value.
Precisamos usar ponteiros aqui. Sabemos que as variáveis são armazenadas em memória e que elas possuem endereços de memória. Então, se queremos alterar o valor de uma variável, precisamos alterar o valor armazenado no endereço de memória. Portanto, a função `add1` precisa saber o endereço de memória de `x` para poder alterar o seu valor. Para isto, passamos`&x`para a função, e alteramos o tipo do argumento para o tipo ponteiro`*int`. Esteja ciente de que nós passamos uma cópia do ponteiro, não uma cópia do valor.
package main
import "fmt"
// simple function to add 1 to a
// Função simples que adiciona 1 a variável a
func add1(a *int) int {
*a = *a+1 // we changed value of a
return *a // return new value of a
*a = *a+1 // alteramos o valor de a
return *a // retornamos o novo valor de a
}
func main() {
x := 3
fmt.Println("x = ", x) // should print "x = 3"
fmt.Println("x = ", x) // deve mostrar "x = 3"
x1 := add1(&x) // call add1(&x) pass memory address of x
fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
fmt.Println("x = ", x) // should print "x = 4"
fmt.Println("x+1 = ", x1) // deve mostrar "x+1 = 4"
fmt.Println("x = ", x) // deve mostrar "x = 4"
}
Now we can change the value of `x` in the functions. Why do we use pointers? What are the advantages?
Agora podemos alterar o valor de `x` dentro da função. Por que usamos ponteiros? Quais são as vantagens?
-Allows us to use more functions to operate on one variable.
-Low cost by passing memory addresses (8 bytes), copy is not an efficient way, both in terms of time and space, to pass variables.
-`string`, `slice`, `map`are reference types, so they use pointers when passing to functions by default. (Attention: If you need to change the length of `slice`, you have to pass pointers explicitly)
-Permite-nos usar mais funções para operar em uma variável.
-Baixo custo passando endereços de memória (8 bytes), a cópia não é uma maneira eficiente, tanto em termo de tempo como de espaço, para passar variáveis.
-`string`, `slice`, `map`são tipos de referências, sendo assim, por padrão eles utilizam ponteiros ao passar para uma função. (Atenção: Se você precisa alterar o comprimento de um `slice`, você precisa passar ponteiros explicitamente)
### defer
Go has a well designed keyword called `defer`. You can have many `defer` statements in one function; they will execute in reverse order when the program executes to the end of functions. In the case where the program opens some resource files, these files would have to be closed before the function can return with errors. Let's see some examples.
Go possui uma palavra-chave bem projetada chamada `defer`. Você pode ter muitas declarações `defer` em uma função. Elas serão executadas em ordem inversa quando o programa executa até o final das funções. No caso onde o programa abre alguns arquivos de recurso, estes arquivos precisam ser fechados antes que a função possa retornar com erros. Vamos ver alguns exemplos.
func ReadWrite() bool {
file.Open("file")
// Do some work
// Faça alguma tarefa
if failureX {
file.Close()
return false
@@ -350,7 +350,7 @@ Go has a well designed keyword called `defer`. You can have many `defer` stateme
return true
}
We saw some code being repeated several times. `defer` solves this problem very well. It doesn't only help you to write clean code but also makes your code more readable.
Vimos algum código sendo repetido várias vezes. `defer`resolve este problema muito bem. Ela não só ajuda você a escrever um código limpo, como também torna seu código mais legível.
func ReadWrite() bool {
file.Open("file")
@@ -364,24 +364,24 @@ We saw some code being repeated several times. `defer` solves this problem very
return true
}
If there are more than one`defer`s, they will execute by reverse order. The following example will print`4 3 2 1 0`.
Se houver mais de uma instrução`defer`, elas serão executadas em ordem inversa. O exemplo a seguir irá mostrar`4 3 2 1 0`.
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
### Functions as values and types
### Funções como tipos e valores
Functions are also variables in Go, we can use`type`to define them. Functions that have the same signature can be seen as the same type.
Funções também são variáveis em Go, podemos utilizar`type`para defini-las. Funções que possuem a mesma assinatura podem ser vistas como sendo do mesmo tipo.
What's the advantage of this feature? The answer is that it allows us to pass functions as values.
Qual é avantagem deste recurso? A resposta é que isto nos permite passar funções como valores.
package main
import "fmt"
type testInt func(int) bool // define a function type of variable
type testInt func(int) bool // define o tipo de uma função como variável
func isOdd(integer int) bool {
if integer%2 == 0 {
@@ -397,7 +397,7 @@ What's the advantage of this feature? The answer is that it allows us to pass fu
return false
}
// pass the function `f` as an argument to another function
// passa a função `f` como um argumento para outra função
func filter(slice []int, f testInt) []int {
var result []int
@@ -412,23 +412,23 @@ What's the advantage of this feature? The answer is that it allows us to pass fu
func main(){
slice := []int {1, 2, 3, 4, 5, 7}
fmt.Println("slice = ", slice)
odd := filter(slice, isOdd) // use function as values
odd := filter(slice, isOdd) // usa a função como valor
fmt.Println("Odd elements of slice are: ", odd)
even := filter(slice, isEven)
fmt.Println("Even elements of slice are: ", even)
}
It's very useful when we use interfaces. As you can see`testInt`is a variable that has function type, and return values and arguments of`filter`are the same as `testInt`. Therefore, we can have complex logic in our programs, while maintaining flexibility in our code.
Isto é muito útil quando utilizamos interfaces. Como você pode ver`testInt`é uma variável que tem tipo de função, e os valores de retorno e argumentos de`filter`são os mesmos de `testInt`. Portanto, podemos ter lógica complexa em nossos programas mantendo a flexibilidade em nosso código.
### Panic and Recover
### Panic e Recover
Go doesn't have `try-catch` structure like Java does. Instead of throwing exceptions, Go uses`panic`and`recover`to deal with errors. However, you shouldn't use `panic` very much, although it's powerful.
Go não possui a estrutura `try-catch` assim como Java. Em vez de lançar exceções, Go usa`panic`e`recover`para lidar com erros. No entanto, embora poderoso, você não deve utilizar a instrução `panic` muito.
Panic is a built-in function to break the normal flow of programs and get into panic status. When a function`F` calls`panic`, `F`will not continue executing but its `defer` functions will continue to execute. Then `F` goes back to the break point which caused the panic status. The program will not terminate until all of these functions return with panic to the first level of that `goroutine`. `panic` can be produced by calling`panic`in the program, and some errors also cause`panic` like array access out of bounds errors.
Panic é uma função interna para quebrar o fluxo normal de programas e entrar em estado de pânico. Quando uma função`F` chama`panic`, `F`não continuará executando, mas suas funções `defer` continuarão a ser executadas. Então `F` volta ao ponto de interrupção que causou o estado de pânico. O programa não terminará até que todas essas funções retornem com panic para o primeiro nível da `goroutine`. `panic` pode ser gerado executando a instrução`panic`no programa, e alguns erros também causam`panic`, como, por exemplo, a tentativa de acessar uma posição inválida em um array.
Recover is a built-in function to recover `goroutine`s from panic status. Calling `recover` in `defer` functions is useful because normal functions will not be executed when the program is in the panic status. It catches `panic` values if the program is in the panic status, and it gets`nil`if the program is not in panic status.
Recover é uma função interna utilizada para recuperar goroutines de estados de pânico. Chamar `recover` nas funções `defer` é útil porque as funções normais não serão executadas quando o programa estiver em estado de pânico. Ele recebe os valores de `panic` se o programa está em estado de pânico, e recebe`nil`se o programa não está em estado de pânico.
The following example shows how to use`panic`.
O seguinte exemplo mostra como utilizar`panic`.
var user = os.Getenv("USER")
@@ -438,7 +438,7 @@ The following example shows how to use `panic`.
}
}
The following example shows how to check`panic`.
O seguinte exemplo mostra como verificar`panic`.
func throwsPanic(f func()) (b bool) {
defer func() {
@@ -446,71 +446,71 @@ The following example shows how to check `panic`.
b = true
}
}()
f() // if f causes panic, it will recover
f() // se f causar pânico, ele irá recuperar
return
}
### `main` function and `init` function
### Função `main` e função `init`
Go has two retentions which are called`main`and`init`, where `init`can be used in all packages and `main` can only be used in the `main` package. These two functions are not able to have arguments or return values. Even though we can write many `init` functions in one package, I strongly recommend writing only one `init` function for each package.
Go possui duas retenções que são chamadas de`main`e`init`, onde `init`pode ser usada em todos os pacotes e `main` só pode ser usada no pacote `main`. Estas duas funções não são capazes de ter argumentos ou valores de retorno. Mesmo que possamos escrever muitas funções `init` em um pacote, recomendo fortemente escrever apenas uma função `init` para cada pacote.
Go programs will call`init()`and`main()` automatically, so you don't need to call them by yourself. For every package, the `init` function is optional, but`package main`has one and only one `main` function.
Programas em Go irão chamar as funções`init()`e`main()` automaticamente, então você não precisa se preocupar em chamá-las. Para cada pacote, a função `init` é opcional, mas o`package main`tem uma e apenas uma função `main`.
Programs initialize and begin execution from the `main` package. If the `main` package imports other packages, they will be imported in the compile time. If one package is imported many times, it will be only compiled once. After importing packages, programs will initialize the constants and variables within the imported packages, then execute the `init` function if it exists, and so on. After all the other packages are initialized, programs will initialize constants and variables in the `main` package, then execute the `init` function inside the package if it exists. The following figure shows the process.
Programas inicializam e começam a execução a partir do pacote `main`. Se o pacote `main` importa outros pacotes, eles serão importados em tempo de compilação. Se um pacote é importado muitas vezes, ele será compilado apenas uma vez. Depois de importar pacotes, os programas irão inicializar as constantes e variáveis dentro dos pacotes importados, e então executar a função `init` se ela existir, e assim por diante. Depois de todos os outros pacotes serem inicializados, os programas irão inicializar as constantes e variáveis do pacote `main` e então executar a função `init` dentro do pacote, se ela existir. A figura a seguir mostra o processo.

Figure 2.6 Flow of programs initialization in Go
Figure 2.6 Fluxo de inicialização de programas em Go
### import
We use`import`very often in Go programs as follows.
Usamos`import`muito frequentemente em programas Go da seguinte forma.
import(
"fmt"
)
Then we use functions in that package as follows.
Então, usamos funções deste pacote da seguinte maneira.
fmt.Println("hello world")
`fmt`is from Go standard library, it is located within $GOROOT/pkg. Go supports third-party packages in two ways.
`fmt`é da biblioteca padrão Go, que está localizada em $GOROOT/pkg. Go suporta pacotes de terceiros de duas maneiras.
1.Relative path
import "./model" // load package in the same directory, I don't recommend this way.
2.Absolute path
import "shorturl/model" // load package in path "$GOPATH/pkg/shorturl/model"
1.Caminho relativo
import "./model" // carrega o pacote no mesmo diretório, eu não recomendo utilizar esta forma.
2.Caminho absoluto
import "shorturl/model" // carrega o pacote no caminho "$GOPATH/pkg/shorturl/model"
There are some special operators when we import packages, and beginners are always confused by these operators.
Existem alguns operadores especiais quando importamos pacotes, e iniciantes na linguagem sempre se confundem com estes operadores.
1.Dot operator.
Sometime we see people use following way to import packages.
1.Operador: ponto.
Às vezes vemos pessoas usando a seguinte forma para importar pacotes.
import(
. "fmt"
)
The dot operator means you can omit the package name when you call functions inside of that package. Now`fmt.Printf("Hello world")`becomes to`Printf("Hello world")`.
2.Alias operation.
It changes the name of the package that we imported when we call functions that belong to that package.
O operador ponto significa que você pode omitir o nome do pacote quando você chamar funções dentro deste pacote. Assim sendo,`fmt.Printf("Hello world")`torna-se`Printf("Hello world")`.
2.Operador: pseudônimo (alias)
Ele altera o nome do pacote que importamos quando chamamos funções que pertencem a este pacote.
This is the operator that is difficult to understand without someone explaining it to you.
Assim sendo,`fmt.Printf("Hello world")`torna-se`f.Printf("Hello world")`.
3.Operador: `_`.
Este operador é difícil de entender sem alguém explicando para você.
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
The `_` operator actually means we just want to import that package and execute its `init` function, and we are not sure if want to use the functions belonging to that package.
O operador `_` na verdade significa que só queremos importar este pacote e executar sua função `init`, e não temos certeza se queremos usar as funções pertencentes a este pacote.
// Example code for Chapter 2.3 from "Build Web Application with Golang"
// Purpose: Shows how to return multiple values from a function
// Código de exemplo do capítulo 2.3 de "Build Web Application with Golang"
// Propósito: mostra como retornar múltiplos valores de uma função
packagemain
import"fmt"
// return results of A + B and A * B
// retorna os resultados de A + B e A * B
funcSumAndProduct(A,Bint)(int,int){
returnA+B,A*B
}
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.