Go (linguagem de programação) – Wikipédia, a enciclopédia livre
Go | |
---|---|
Paradigma | |
Surgido em | 10 de novembro de 2009 (15 anos)[1] |
Última versão | 1.22.2 (3 de abril de 2024[2]) |
Criado por | |
Estilo de tipagem |
|
Principais implementações | |
Influenciada por | |
Influenciou | Zig |
Licença | BSD[4] |
Extensão do arquivo | .go |
Página oficial | go |
Go é uma linguagem de programação criada pela Google e lançada em código livre em novembro de 2009. É uma linguagem compilada e focada em produtividade e programação concorrente,[6] baseada em trabalhos feitos no sistema operacional chamado Inferno.[7] O projeto inicial da linguagem foi feito em setembro de 2007 por Robert Griesemer, Rob Pike e Ken Thompson.[6] Atualmente, há implementações para Windows, Linux, Mac OS X e FreeBSD.[4]
História
[editar | editar código-fonte]Go foi criado em 2009 e desde então vem recebendo muitas atualizações, tendo seu mais recente lançamento em 2 de Agosto de 2022, versão Go 1.19. Veja mais informações sobre versões anteriores em https://go.dev/project.
Poucos dias após o lançamento da linguagem, Fancis McCabe, desenvolvedor da linguagem chamada Go!, solicitou uma mudança de nome da linguagem do Google, para evitar confusões. McCabe criou Go! em 2003, mas não registrou o nome.[8]
Design
[editar | editar código-fonte]A sintaxe de Go é semelhante a C e suas declarações são feitas com base em Pascal limpo; uma variação é a declaração de tipos, a ausência de parênteses em volta das estruturas for
e if
. Possui coletor de lixo. Seu modelo de concorrência é baseado no CSP de Tony Hoare,[6] além de possuir características do cálculo pi, como passagem por canal.
Algumas funcionalidades ausentes são tratamento de exceção, Herança, programação genérica, assert
e sobrecarga de métodos.[6] Os autores expressam abertura para discutir programação genérica, mas argumentam abertamente contra asserções e defendem a omissão de herança de tipos em favor da eficiência.[6] Ao contrário de Java, vetores associativos são parte intrínseca da linguagem, assim como strings.
Atualmente, há dois compiladores para Go. 6g e ferramentas complementares - conhecidos em conjunto como gc - são escritos em C, usando yacc e bison para análise sintática. Além do gc, há o gccgo, um compilador de Go com front-end C++ (utilizando um analisador sintático descendente recursivo) associado ao back-end padrão do GCC.[5][3]
Orientação a objetos
[editar | editar código-fonte]É possível programar orientado a objetos, mas não da forma mais comum, pois Go não utiliza classes e sim estruturas. Na orientação a objetos, são criados métodos sem classes, interface sem hierarquia, e reutilização de código sem herança.
type Pessoa struct { Nome string idade int }
package main import "fmt" type Animal struct { } func (a Animal) Comer() { fmt.Println("Comendo") } type MembroFamilia struct { } func (fm MembroFamilia) Nome() { fmt.Println("Meu nome não é Johnny") } type Cachorro struct { Animal // Struct incorporada/embedada MembroFamilia // Struct incorporada/embedada } func main() { d := Cachorro{} d.Comer() // Printa "Comendo" d.Nome() // Printa "Meu nome não é Johnny" }
Funções
[editar | editar código-fonte]Go também possui funções como outras linguagens, as funções podem retornar valores únicos, múltiplos e até mesmo retornar outra função.
package main import "fmt" func somar (a int ,b int) int { return a + b } func main() { res := somar(1, 2) fmt.Println("1 + 2 = ", res) }
Exemplo de múltiplos retornos:
package main import "fmt" func atribuiValor() (int, int) { return 15,22 } func main() { //Aqui queremos atribuir dois valores nas //variaveis a e b a, b:= atribuiValor() fmt.Println("A = ", a) fmt.Println("B = ", b) //Podemos também apenas escolher um valor //a ser retornado _, c := atribuiValor() fmt.Println("C = ", c) }
Em Go uma função pode receber um número variável de parâmetros, ou seja, não se sabe ao certo quantos parâmetros serão recebidos.
package main import "fmt" func variaveis(nums ...int) int { //Imprimindo os valores recebidos fmt.Print(nums," ") total := 0 for _, num := range nums { //Fazendo a soma dos valores recebidos total += num } fmt.Println("Total = ", total) } func main() { variaveis(1,4,7)// Resultado impresso "12" variaveis(4,2)// Resultado impresso "6" //Pode se enviar um vetor como parâmetro v := []int{0,1,2,3,4,5,6}// Resultado impresso "21" variaveis(v...) }
Funções também podem receber outras funções como parâmetros.
package main import "fmt" func intSeq() func() int { i := 0 return func() int { i += 1 return i } } func main() { nextInt := intSeq() // Aqui "nextInt" recebe como valor a função intSeq fmt.Println(nextInt()) // Printa 1 fmt.Println(nextInt()) // Printa 2 fmt.Println(nextInt()) // Printa 3 newInts := intSeq() fmt.Println(newInts()) // Printa 1 }
Exceções
[editar | editar código-fonte]O Go (ao contrário do Java) não possui exceções como try / catch / finally blocks. Ele possui tratamento estrito de erros com funções chamadas de panic e recover e uma instrução chamada defer.
Um uso comum de pânico é abortar se uma função retornar um valor de erro que não sabemos como (ou queremos) manipular. Executar este programa fará com que ele entre em pânico, imprima uma mensagem de erro e rastreie goroutine e saia com um status diferente de zero.
package main import "os" func main() { panic("a problem") _, err := os.Create("/tmp/file") if err != nil { panic(err) } }
recover
é uma função embutida que recupera o controle de uma gorout em pânico. Recuperar só é útil dentro de funções diferidas. Durante a execução normal, uma chamada para recuperar retornará nula e não terá outro efeito. Se a gorout atual estiver em pânico, uma chamada para recuperar capturará o valor dado ao pânico e retomará a execução normal. Um defer
empurra uma chamada de função para uma lista. A lista de chamadas salvas é executada após a função circundante retornar. Adiar é comumente usado para simplificar funções que executam várias ações de limpeza.
package main import ( "fmt" "os" ) func main() { f := createFile("/tmp/defer.txt") defer closeFile(f) writeFile(f) } func createFile(p string) *os.File { fmt.Println("creating") f, err := os.Create(p) if err != nil { panic(err) } return f } func writeFile(f *os.File) { fmt.Println("writing") fmt.Fprintln(f, "data") } func closeFile(f *os.File) { fmt.Println("closing") f.Close() }
Métodos
[editar | editar código-fonte]Go suporta métodos definidos em tipos struct. Métodos podem ser definidos para qualquer tipo de receptor ponteiro ou valor. Go trata automaticamente conversões entre valores e ponteiros para métodos de chamada. Você pode querer usar um ponteiro do tipo receptor para evitar a cópia de um método de chamada ou para permitir que o método faça mutação da estrutura recebida.
package main import "fmt" type rect struct { width, height int } func (r *rect) area() int { return r.width * r.height } func (r rect) perim() int { return 2*r.width + 2*r.height } func main() { r := rect{width: 10, height: 5} fmt.Println("area: ", r.area()) // Printa area: 50 fmt.Println("perim:", r.perim()) // Printa perim: 30 rp := &r fmt.Println("area: ", rp.area()) // Printa area: 50 fmt.Println("perim:", rp.perim()) // Printa perim: 30 }
Interface
[editar | editar código-fonte]Interface nada mais é que um conjunto de métodos.
package main import ( "fmt" "math" ) type geometria interface { area() float64 perim() float64 } type quadrado struct { largura, altura float64 } type círculo struct { raio float64 } func (q quadrado) area() float64 { return q.largura * q.altura } func (q quadrado) perim() float64 { return 2*q.largura + 2*q.altura } func (c círculo) area() float64 { return math.Pi * c.raio * c.raio } func (c círculo) perim() float64 { return 2 * math.Pi * c.raio } func medir(g geometria) { fmt.Println(g) // Printa os valores da forma geometrica recebida ex: quadrado = altura e largura fmt.Println(g.area()) // Printa a area da forma recebida fmt.Println(g.perim()) // Printa o perimetro da forma recebida } func main() { q := quadrado{largura: 3, altura: 4} c := círculo{raio: 5} medir(q) medir(c) }
Goroutines
[editar | editar código-fonte]Goroutine é uma forma de implementação paralela, o comando usado é go, ele passa como parâmetro uma função para que ela seja executada em paralelo.
package main import "fmt" func f(from string) { for i := 0; i <3; i++ { fmt.Println(from,":",i) } } func main() { f("direct") go f("goroutine") // Será executado por uma thread go func(msg string) { // Será executado por outra thread fmt.Println(msg) }("going") var input string fmt.Scanln(&input) fmt.Println("done") }
Ferramentas
[editar | editar código-fonte]A comunidade Go considera muito importante o uso da ferramenta 'gofmt' para realizar a formatação do código-fonte uniforme e automaticamente. [9][10]
“ | O estilo do gofmt não é o favorito de ninguém, mas gofmt é o favorito de todos. | ” |
— Rob Pike |
Exemplos
[editar | editar código-fonte]Programa Olá Mundo
[editar | editar código-fonte]package main import "fmt" func main() { fmt.Println("Olá, Mundo!") }
Pode ser compilado e executado com o seguinte comando:[11]
$ go build hello.go $ ./hello
Algoritmo de Trabb Pardo-Knuth
[editar | editar código-fonte]package main import ( "fmt" "math" ) func f(t float64) float64 { return math.Sqrt(math.Abs(t)) + 5*math.Pow(t, 3) } func main() { var a [11]float64 for i := range a { fmt.Scan(&a[i]) } for i := len(a) - 1; i >= 0; i-- { if y := f(a[i]); y > 400 { fmt.Println(i, "TOO LARGE") } else { fmt.Println(i, y) } } }
Concorrência
[editar | editar código-fonte]Exemplo retirado da página oficial:[12]
package main import ( "fmt" "math" ) func main() { fmt.Println(pi(5000)) } func pi(n int) float64 { ch := make(chan float64) for k := 0; k <= n; k++ { go term(ch, float64(k)) } f := 0.0 for k := 0; k <= n; k++ { f += <-ch } return f } func term(ch chan float64, k float64) { ch <- 4 * math.Pow(-1, k) / (2*k + 1) }
Interface de linha de comandos
[editar | editar código-fonte]Exemplo de uma implementação do echo do Unix:[13]
package main import ( "flag" "os" ) var omitNewline = flag.Bool("n", false, "Não emitir o caractere de nova linha do final") const ( Space = " " Newline = "\n" ) func main() { flag.Parse() var s string = "" for i := 0; i < flag.NArg(); i++ { if i > 0 { s += Space } s += flag.Arg(i) } if !*omitNewline { s += Newline } os.Stdout.WriteString(s) }
Ver também
[editar | editar código-fonte]Referências
- ↑ a b Della Valle, James (12 de novembro de 2009). «Google apresenta linguagem GO». INFO Online. Editora Abril. Consultado em 12 de novembro de 2009
- ↑ «Release History - The Go Programming Language». golang.org. 3 de abril de 2024. Consultado em 1 de maio de 2024
- ↑ a b «FAQ» (em inglês). Consultado em 12 de novembro de 2009
- ↑ a b c «Installing Go» (em inglês). Consultado em 14 de setembro de 2012
- ↑ a b «GCC Front Ends». gcc.gnu.org (em inglês). 28 de julho de 2021. Consultado em 16 de outubro de 2021
- ↑ a b c d e f «Language Design FAQ» (em inglês). Consultado em 9 de julho de 2016
- ↑ «5.c - go - Project Hosting on Google Code». Consultado em 12 de novembro de 2009
- ↑ Claburn, Thomas (11 de novembro de 2009). «Google 'Go' Name Brings Accusations Of 'Evil'». InformationWeek (em inglês). United Business Media. Consultado em 12 de novembro de 2009
- ↑ «go fmt your code» (em inglês). Consultado em 30 de julho de 2019
- ↑ «Gofmt knows best» (em inglês). Consultado em 30 de julho de 2019
- ↑ «Getting Started - The Go Programming Language». golang.org (em inglês). Consultado em 6 de agosto de 2020
- ↑ «The Go Programming Language». golang.org (em inglês). Consultado em 24 de fevereiro de 2021
- ↑ «A Tutorial for the Go Programming Language» (em inglês). Consultado em 12 de novembro de 2009
- Este artigo foi inicialmente traduzido, total ou parcialmente, do artigo da Wikipédia em inglês cujo título é «Go (programming language)», especificamente desta versão.
- Este artigo incorpora material do tutorial oficial de Go Let's Go, que é licenciado sob Creative Commons Attribution 3.0 .
Ligações externas
[editar | editar código-fonte]- Sítio oficial
- Go no GitHub
- «The Go Playground» (em inglês). Experimente Go online