GoLang — Simplificando a complexidade “O Inicio”
Published: 2023-04-12 17:44:58

Existem inúmeras linguagens de programação e cada uma nasceu com um propósito: “**resolver problemas**”. As linguagens são ferramentas onde teremos que saber utilizá-las no momento certo. Falando “**como desenvolvedor**” quanto mais poliglota conseguir ser melhor será para sua carreira profissional e para um melhor entendimento e compreensão da diversidade deste ecossistema.

O **objetivo** deste post é apresentar o que é a linguagem **Go** e, porque ela é tão poderosa. Apresentando **alguns conceitos e pontos importantes sobre a linguagem Go** que muita das vezes é expressado de forma equivocada em diversos artigos encontrados na internet e grupos de discussões de linguagens de programação. Acredito que os pontos fracos e problemas gerados por diversas outras linguagens de programação ao longo destas décadas fez com que **Go** torna-se o que é hoje. E para explicarmos como isto é possível iremos voltar ao início de tudo, onde tudo começou.

```go
package main

func main() {
    println("Hello all folks!")
}
```

# Menos é exponencialmente Mais

A equipe de desenvolvedores do **Go** dizem que sua criação é uma tentativa de tornar os programadores mais produtivos. Melhorando o processo de desenvolvimento de software no *Google*. O primeiro objetivo foi criar uma linguagem melhor para enfrentar os desafios da *simultaneidade escalável*, ou seja software que lida com muitas preocupações simultaneamente, um exemplo seria a coordenação de mil servidores *back-end* enviando tráfego de rede todo o tempo.

Manter a linguagem **Go** pequena permite objetivos mais importantes. Ser pequeno torna o **Go** mais fácil de **aprender**, mais fácil de **entender**, mais fácil de **implementar**, mais fácil de **reimplementar**, mais fácil de **depurar**, mais fácil de **ajustar** e mais fácil de **evoluir**. Fazer menos permite mais. É uma expressão utilizada pela equipe de desenvolvimento do **Go**: “*Do Less. Enable More*” seria o equilíbrio entre os universo de problemas existentes e o que **Go** poderá ajudar a resolver bem tais problemas. **Go** explicitamente não foi projetado para resolver todos os problemas em vez disso fizeram o suficiente para possamos criar as próprias soluções personalizadas com facilidade, mas deixando bem claro que **Go** não pode fazer tudo.

Go foi projetado pelo **Google** em **2007** para melhorar a produtividade de programação em uma era de **multicore,** rede de máquinas e grandes bases de código. Os designers queriam abordar críticas de outras línguas em uso no Google, mas manter suas características úteis.  
Os criadores [Rob Pike](https://en.wikipedia.org/wiki/Rob_Pike), [Ken Thompson](https://en.wikipedia.org/wiki/Ken_Thompson) e [Robert Griesemer](https://de.wikipedia.org/wiki/Robert_Griesemer) mantiveram a sintaxe de **Go** semelhante ao **C**. No final de 2008 [Russ Cox](https://en.wikipedia.org/wiki/Go_(programming_language)) juntou-se a equipe e ajudou a mudar a linguagem e as bibliotecas de protótipo para realidade.

A linguagem Go foi lançada em **2009** com propósito de facilitar a resolução de problemas quando o assunto é desenvolvimento em **camadas de rede, escalabilidade, desempenho, produtividade e o mais importante concorrência**. O próprio [Rob Pike](https://pt.wikipedia.org/wiki/Rob_Pike) declarou que “*Go foi projetado para tratar de um conjunto de problemas de engenharia de software a que estávamos expostos na construção de grandes softwares de servidor*”.

**Go** teve influências de diversas linguagens de programação e **paradigmas** **diferentes** dentre elas**:** [*Alef*](https://en.wikipedia.org/wiki/Go_(programming_language))*,* [*APL*](https://pt.wikipedia.org/wiki/APL_(linguagem_de_programa%C3%A7%C3%A3o))*,* [*BCPL*](https://pt.wikipedia.org/wiki/BCPL)*,* [*C*](https://pt.wikipedia.org/wiki/C_(linguagem_de_programa%C3%A7%C3%A3o))*, CSP,* [*Limbo*](https://pt.wikipedia.org/wiki/Limbo_(linguagem_de_programa%C3%A7%C3%A3o))*,* [*Modula*](https://pt.wikipedia.org/wiki/Modula)*,* [*Newsqueak*](https://en.wikipedia.org/wiki/Newsqueak)*,* [*Oberon*](https://pt.wikipedia.org/wiki/Oberon_(linguagem_de_programa%C3%A7%C3%A3o))*,* [*occam*](https://pt.wikipedia.org/wiki/Occam_(linguagem_de_programa%C3%A7%C3%A3o))*,* [*Pascal*](https://en.wikipedia.org/wiki/Pascal_(programming_language))*,* [*Smalltalk*](https://pt.wikipedia.org/wiki/Smalltalk) *e* [*Cristal*](https://en.wikipedia.org/wiki/Crystal_(programming_language))*,* percebe-se que utilizaram do que tinham de melhor e criou algo novo e enxuto, com o mínimo necessário para resolver os problemas propostos, sem perder sua simplicidade. Acredito que isto podemos chamar de ***inovação***. **Go** inovou ao quebrar os **paradigmas de linguagens** e implementar algo novo de forma simples e muito poderosa.

# Polêmicas

Foram ***deixadas de fora*** diversas características que as ***linguagens modernas*** contrariando e indo em direção oposta das outras linguagens atuais algumas funcionalidades como o uso de: ***declarações de imutabilidade, tipos de dados de correspondência de padrões, generics,*** [***tratamento de exceção***](https://pt.wikipedia.org/wiki/Tratamento_de_exce%C3%A7%C3%A3o)***,*** [***Herança***](https://pt.wikipedia.org/wiki/Heran%C3%A7a_(programa%C3%A7%C3%A3o))***,*** [***programação genérica***](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_gen%C3%A9rica) ***e*** [**sobrecarga**](https://pt.wikipedia.org/wiki/Sobrecarga) **de métodos** e diversos outros pontos. Todos os recursos acima foram criticados e apontados para os criadores de ***Go,*** que responderam: “***Essas omissões foram simplificações que contribuem para a força de Go****”.* Há muitas coisas na linguagem e bibliotecas **Go** que diferem das práticas modernas, foi uma decisão da equipe de desenvolvimento do **Go: *“****às vezes vale a pena tentar uma abordagem diferente”.*

Todos estão convidados **a ajudar e contribuir** se assim desejar, podem abrir [**propostas**](https://github.com/golang/go/wiki/ExperienceReports) para novos recursos e tudo relacionado ao ecossistema da linguagem. O código fonte de **Go** está disponível no [**GitHub**](https://github.com/golang/go) . A documentação sobre como você pode contribuir com o idioma é fornecida [**aqui**](https://golang.org/doc/contribute.html)**.**

# Goroutines em vez de threads

Um dos principais objetivos da linguagem de programação Go é tornar a simultaneidade mais simples, rápida e eficiente.

Goroutines são leves e tiram proveito de todo o poder de processamento disponível. Goroutines existe apenas no espaço virtual do tempo de execução Go e não no sistema operacional.

Goroutine é um método/função que pode ser executado independentemente junto com outras goroutines. Cada atividade simultânea na linguagem Go é geralmente denominada Goroutine.

Um dos pontos mais relevantes e importantes é o trabalho com **concorrência**, ele **inovou** ao quebrar o modelo **tradicional de** [**threads**](https://pt.wikipedia.org/wiki/Thread_(computa%C3%A7%C3%A3o)) e sua forma de utilização ao criar um novo modelo, as [***goroutines***](https://golang.org/doc/effective_go.html#concurrency). As **goroutines** são responsáveis por realizar execuções em **Go** de forma **assíncrona**. São muito poderosas e uma simples máquina de **1G de Ram** poderá subir milhares delas.

**Goroutines** fazem parte de tornar a **simultaneidade** **fácil** de usar. As **goroutines**, pode ser muito barata: eles têm pouca sobrecarga além da memória para a pilha, que é apenas alguns kilobytes. Para tornar as pilhas pequenas, o tempo de execução de **Go** usa pilhas redimensionáveis ​​e delimitadas. Uma **goroutine** recém lançada recebe alguns kilobytes, o que é quase sempre suficiente. Quando não é, o tempo de execução aumenta (e encolhe) a memória para armazenar a pilha automaticamente, permitindo que muitos **goroutines** vivam em uma **quantidade modesta de memória**. A sobrecarga da CPU tem em média três instruções baratas por chamada de função. É prático criar **centenas de milhares de goroutines** no mesmo espaço de endereço. Se **goroutines** fossem apenas **threads**, os recursos do sistema acabariam em um número muito menor.

O design de **Go** foi fortemente influenciado pelo artigo de [C.A.R. Hoare](https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf) **1978** “[Communicating sequential processes](https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf)” (*Comunicação de processos sequenciais*).

# Simultaneidade nas ideias do CSP

Um dos modelos mais bem-sucedidos para fornecer suporte linguístico de alto nível para concorrência é o ***Hoare’s*** ***Communicating Sequential Processes***, ou [**CSP**](https://en.wikipedia.org/wiki/Communicating_sequential_processes)**.** [**Occam**](https://pt.wikipedia.org/wiki/Occam_(linguagem_de_programa%C3%A7%C3%A3o)) **e** [**Erlang**](https://pt.wikipedia.org/wiki/Erlang_(linguagem_de_programa%C3%A7%C3%A3o)) são duas línguas bem conhecidas que derivam de [**CSP**](https://en.wikipedia.org/wiki/Communicating_sequential_processes). As primitivas de concorrência de **Go** derivam de uma parte diferente da árvore genealógica cuja principal contribuição *é a poderosa noção de canais como objetos de primeira classe*. A experiência com várias linguagens anteriores mostraram que o modelo [**CSP**](https://en.wikipedia.org/wiki/Communicating_sequential_processes) se encaixa bem em uma estrutura de linguagem procedural.

A maior diferença entre **Go** e o modelo [**CSP**](https://en.wikipedia.org/wiki/Communicating_sequential_processes), além da sintaxe, é que o **Go** modela os canais de comunicação **simultânea explicitamente como canais**, enquanto os processos da linguagem de ***Hoare*** enviam mensagens diretamente uns aos outros, semelhante ao [**Erlang**](https://pt.wikipedia.org/wiki/Erlang_(linguagem_de_programa%C3%A7%C3%A3o)).

Bem para chegar neste resultado **Go** novamente sofreu críticas do modelo adotado. **Go** incorpora uma variante do [**CSP**](https://en.wikipedia.org/wiki/Communicating_sequential_processes) (*Comunicação de processos sequenciais*) é uma linguagem formal para descrever padrões de interação em sistemas concorrentes com canais de primeira classe. Não foi adotada uma abordagem de gravação única para valorizar a semântica no contexto da [computação concorrente](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_concorrente) como é feita no [**Erlang**](https://pt.wikipedia.org/wiki/Erlang_(linguagem_de_programa%C3%A7%C3%A3o)), ao invés disto adotaram algo prático e que resultou em algo **poderoso**, permitindo programação **simultânea simples** e **segura**, mas *não proíbe programação incorreta*. E o lema criado foi: “*Não se comunique compartilhando memória, compartilhe memória comunicando-se*”.  
A simplicidade e o suporte para concorrências oferecidas por **Go** gera robustez.

# Concorrência é diferente de Paralelismo

Uma das famosas frases é: ***“Concorrência é sobre lidar com muitas coisas ao mesmo tempo. Paralelismo é fazer muitas coisas ao mesmo tempo”.* Concorrência** é a **composição** de cálculos de execução independente. **Concorrência** é uma maneira de estruturar software, e definitivamente não é paralelismo embora permita o paralelismo.  
Se você tiver apenas um processador, seu programa ainda pode ser concorrente, mas não pode ser paralelo. Por outro lado, um programa concorrente bem escrito pode ser executado de forma eficiente em paralelo em um multiprocessador. Sugiro dar uma conferida neste vídeo de uma palestra do [Rob Pike](https://pt.wikipedia.org/wiki/Rob_Pike) “[Concorrência não é Paralelismo](https://vimeo.com/49718712)”.

**Concorrência** em **Go** é muito poderosa e também simples de codar está foi a intensão dos engenheiros que desenvolveram **Go**. A resolução de muitos problemas é bem mais eficiente utilizando **concorrência** e este é o **poder** de **Go**, por isto, se tornou um **Deus** quando o assunto é **concorrência**. Devido a isto, problemas englobados neste universo serão resolvidos com muita **eficiência** e o mais importante, com muito **pouco recurso computacional**.

Quando falamos de **concorrência** temos que ressaltar que existem alguns **patterns** e descrevo eles logo abaixo, e existe alguns **tipos de cargas de trabalhos** eles serão nossa bússola para determinar nosso ponto de equilíbrio quando tivermos que resolver problemas evolvendo concorrência.

# Workloads: CPU-Bound & IO-Bound

Uma **thread** pode fazer **dois tipos de cargas de trabalhos (***Workloads***)**: **CPU-Bound** e o **IO-Bound.**

**CPU-Bound**: Esta carga de trabalho nunca irá cria uma situação em que a **thread** pode ser colocado em ***estados de espera***. Ele estará constantemente fazendo cálculos. Uma **thread** calculando *pi* para décima oitava potência seria limitado pela **CPU.** *(curiosidade:* [***Emma Haruka Iwao***](https://pt.wikipedia.org/wiki/Emma_Haruka_Iwao) *é uma* ***cientista da computação*** *japonesa e Engenheira de Desenvolvimento Cloud do Google. Em 2019, Haruka Iwao calculou o valor de pi mais preciso do mundo, que incluiu 31,4 trilhões de dígitos).* Este tipo de carga de trabalho, trabalhos ligadas à CPU, você precisa do paralelismo para aproveitar a simultaneidade, mais goroutines não irá ajuda-lo e não serão eficientes, podendo atrasar ainda mais as cargas de trabalho a serem executadas, isto ocorre devido ao custo de latência (o tempo gasto) de mover Goroutines dentro e fora da thread do sistema operacional.

**IO-Bound**: Neste tipo de carga de trabalho as threads entram em estados de espera. Um bom exemplo seria uma solicitação de acesso a um recurso pela rede ou fazer chamadas para o sistema operacional. Uma thread que precisa acessar um banco de dados, eventos de sincronização *(mutex,* atomic*)*, todos estes exemplos fazem com que a thread aguarde então poderíamos dizer que são do tipo de trabalho **IO-Bound**. Neste tipo de carga de trabalho você não precisa de paralelismo para usar a simultaneidade um único core físico já seria suficiente para uma boa execução de várias Goroutines. As Goroutines estão entrando e saindo dos estados de espera como parte de sua carga de trabalho. Neste tipo de carga de trabalho ter mais Goroutines do que cores físicos pode acelerar a execução porque o custo de latência de mover Goroutines dentro e fora do thread do sistema operacional não está criando um evento. Sua carga de trabalho é naturalmente interrompida e isso permite que um Goroutine diferente aproveite o mesmo core físico ao invés de permitir que ele fique ocioso.

# Goroutine e Pattern

Existem alguns patterns para concorrência, dentre eles: **Fan-In** e **Fan-Out**.  
**Fan-Out:  
**Múltiplas funções podem ler do mesmo canal até que esse canal seja fechado, isso é chamado de ***fan-out*** . Isso fornece uma maneira de distribuir o trabalho entre um grupo de trabalhadores para fazer uso da **CPU** e **E/S** de forma concorrente.

[**Fan-In**](https://blog.golang.org/pipelines)**:**  
É a forma de ler a partir de múltiplas entradas e prosseguir até que todas estejam fechadas, multiplexando os canais de entrada em um único canal que está fechado quando todas as entradas estão fechadas. Isso é chamado ***fan-in***.

**Pipeline:  
**Não há definição formal de um pipeline em Go, é apenas um dos muitos tipos de programas concorrentes. Informalmente, um pipeline é uma série de *estágios* conectados por canais, onde cada estágio é um grupo de goroutines executando a mesma função. Em cada etapa, os goroutines:

* Recebem valores do *upstream* via canais de *entrada;*
    
* Executam alguma função nesses dados, geralmente produzindo novos valores;
    
* Enviam valores a *jusante* através de canais de *saída.*
    

Cada estágio possui vários canais de entrada e saída, exceto o primeiro e o último estágio, que possuem apenas canais de entrada ou saída, respectivamente.

Para se ter uma pequena ideia, em uma máquina de **1CPU e 1G Ram**, conseguimos com uma **API simples** feita em **Go,** com poucas linhas de código, aguentar de **5k a 6k** de requisições por segundo em um protocolo [**TCP**](https://pt.wikipedia.org/wiki/Transmission_Control_Protocol), utilizando [**RPC**](https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto) ou **TCP** nativo e gravando em um banco de dados relacional como o **Postgresql**, sem derrubá-lo e consumindo em média somente **60Mb** a **70Mb** de memória e de 8% a 15% de CPU para que isto seja possível utilizamos um “Worker Poll” que é um [Fan-out](https://blog.golang.org/pipelines).

Que aprofundar ainda mais sobre concorrência? Só entrar neste [link](https://github.com/golang/go/wiki/LearnConcurrency). Quer testar e visualizar alguns exemplos? [Click Aqui](https://github.com/jeffotoni/goexample/tree/master/goroutine).  
Vamos criar um post só para falarmos sobre **Goroutine** é um tópico extenso muito cheio de detalhes e muitas situações interessantes. Sabemos que o suporte a concorrência em **Go** o torna um **Deus** perante aos problemas que são melhores resolvidos usando concorrência.

**Go** é uma linguagem **compilada**, um ***like de C***, muito focada na produtividade. Para projetos simples ou complexos Go sempre será uma excelente alternativa, pois torna tudo mais simples e enxuto, fácil de codar e dar manutenção.

```go
package main

import "fmt"

func main() {
    fmt.Printf("Olá, eu amo Go!\n")
}
```

# Não existe ainda bala de prata

Uma solução ou ferramenta para resolver todos os problemas não existe ainda é claro. O que sabemos é que existe uma infinidade de soluções desenvolvidas em diversas linguagens todas com um propósito e cada uma delas tem suas características. Por este motivo existem ***paradigmas de programação*** é uma forma de classificar as linguagens baseado em suas funcionalidades facilitando o entendimento e o contexto que ela poderá está melhor inserida e é claro com isto teremos uma visão sobre sua estruturação e execução das linguagens.

Esta cada vez mais comum linguagens suportarem múltiplos paradigmas. Sabemos que existem classes diferentes na computação quando o assunto é resolver problemas, quanto mais próximos destes assuntos estivermos, mais confortáveis estaremos para escolher uma determinada linguagem para resolver problemas, e assim sabermos qual ferramenta usar no momento certo. Na prática esta tarefa não é tão fácil mas o que sabemos é que ainda não criaram a bala de prata para resolver todos os problemas de uma única vez com apenas uma linguagem, se existisse não existiria mais [**P versus NP**](https://pt.wikipedia.org/wiki/P_versus_NP) e todos os problemas poderiam ser resolvidos em tempo polinomial.

# As coisas Boas de Go

* Não possui Generics;
    
* Não possui sobrecarga do operador;
    
* Não possui aritmética de ponteiros;
    
* Não é explícito o gerenciamento de Threads;
    
* Possui inferência de tipos;
    
* As Dependências são claras;
    
* A sintaxe é limpa;
    
* A semântica é clara;
    
* A composição e não herança;
    
* GC Nativo (Garbage collector);
    
* Possui Goroutines;
    
* Suporte nativo a programação concorrente;
    
* Funções de Primeira Classe (*podemos passar funções como parâmetros*);
    
* Multiplataforma;
    
* Open Source;
    
* Curva de Aprendizado muito baixa ou seja fácil de aprender;
    
* Altamente produtivo;
    
* Resolve problemas de escalabilidade;
    
* Pode diminui seus custos de servidores drasticamente;
    
* Diversos problemas pensados na perspectiva Go torna-se muito mais fáceis de tratar e resolvê-los;
    
* Possui somente 25 Palavras reservadas;
    
* Multi-paradigma: concorrente, funcional, imperativa, orientada a objeto;
    
* Memory Safe.
    

Sabemos que diversos pontos acima serão criticados mas na prática e com o tempo percebemos que todas as simplificações omitidas tornaram **Go** uma linguagem ainda mais poderosa.

# Não há Generics ainda

Existem motivos fortes de **Go** não ter implementado **Generics no inicio do projeto,** há uma discussão nas comunidades em geral sobre este tema. **Go** deixou de fora diversas funcionalidades, dentre elas: **“Generics”** que em sua concepção iria comprometer diretamente o desempenho e propósito que a linguagem **Go** propusera a resolver. Os que reclamam são em sua grande maioria desenvolvedores que vieram de linguagens que usam esse recurso.  
No dia 29 de novembro de 2018 os responsáveis pela manutenção do código fonte de **Go** abriram a possibilidade de enviarem proposta de novas funcionalidades com todos os detalhes para que possam  
analisá-las e talvez implementá-las na versão Go 2.0, para terem uma boa noção leiam este arquivo [clicando aqui.](https://blog.golang.org/go2-here-we-come)

**Generics** é uma forma de fazer **cast** de tipos diferentes em métodos e classes. É um tipo de Polimorfismo de inclusão e paramétrico, são funções que operam da mesma forma sobre objetos de tipos diferentes ou seja funções genéricas.

*Exemplo:*  
1\. Imagina um método que recebe um vetor do tipo **int**, e imprima na tela.  
2\. Imagina que precise fazer isso agora com tipo String e do tipo **float**, teria que fazer novos métodos ou funções várias vezes, repetindo o código.

*Solução:  
*Para não precisar criar vários métodos é criado somente um método como generics para poder receber qualquer tipo.

Percebe-se que isso só é problemas em linguagens que precisam declarar tipos de variáveis ou funções etc, em linguagens dinâmicas como PHP por exemplo não tem essa necessidade, não vou dizer linguagens fortemente tipadas ou fracamente tipadas pois é um pouco mais complexo que isso e isto levaria a um outra discussão.

Em **Go** conseguimos resolver todos os problemas dessa natureza usando [reflect](https://golang.org/pkg/reflect/) e outras usando interface. **Go** adota uma abordagem incomum para programação orientada a objeto então não faz muito sentido no momento ter uma funcionalidade que não agrega tanto para contribuir com o verdadeiro propósito que a linguagem foi construída, além do recurso deixar todo processo de execução e compilação bem mais lento e complexo.

Porém no ano de **2020** a proposta para **Generics** ficou ainda mais próximo de tornar-se realidade não temos dúvidas que veem algo por aí relacionado ao Generics então vamos ver na prática como isto seria possível usando [Go.😎](http://go.xn--s28h/)

Abaixo três exemplos com três propostas para resolver o problema desta forma irá conseguir perceber quando falamos em Generics😊.

## Copiando e Colando funções com tipos específicos

```go
package main

// Pega um slice de qualquer tipo e a inverte.
func Reverses(list []string) []string {
	i := 0
	j := len(list) - 1
	for i < j {
		list[i], list[j] = list[j], list[i]
		i++
		j--
	}
	return list
}

// Pega um slice de qualquer tipo e a inverte.
func Reversei(list []int) []int {
	i := 0
	j := len(list) - 1
	for i < j {
		list[i], list[j] = list[j], list[i]
		i++
		j--
	}
	return list
}

func main() {
	s := []string{"otoni","jeff","Go"}
	Reverses(s)
	println(s[0], s[1], s[2])
	
	i := []int{2020,2012,2009}	
	Reversei(i)	
	println(i[0], i[1], i[2])
}
```

## Usando Interface

```go
package main

// Pega um slice de qualquer tipo e a inverte.
func Reverse(in interface{}) interface{} {
	switch in.(type) {
	    case []string:
		list := []string(in.([]string))
		i := 0
		j := len(list) - 1
		for i < j {
	     	   list[i], list[j] = list[j], list[i]
		   i++
		   j--
	        }
	        return list
	    
	     case []int:
		list := []int(in.([]int))
		i := 0
		j := len(list) - 1
		for i < j {
		   list[i], list[j] = list[j], list[i]
		   i++
		   j--
	        }
	        return list
	}
	return nil
}

func main() {
	s := []string{"otoni","jeff","Go"}
	Reverse(s)
	println(s[0], s[1], s[2])
	
	i := []int{2020,2012,2009}	
	Reverse(i)	
	println(i[0], i[1], i[2])
}
```

## Utilizando Generics

```go
// https://go2goplay.golang.org/
package main

import (
	"fmt"
)

// The playground now supports parentheses or square brackets (only one at
// a time) for generic type and function declarations and instantiations.
// By default, parentheses are expected. To switch to square brackets,
// the first generic declaration in the source must use square brackets.

func Print[type T] (s []T){
	for _, v := range s {
		fmt.Print(v)
	}
	fmt.Println("")
}

func Reverse[type T](list []T) {
	i := 0
	j := len(list) - 1
	for i < j {
		list[i], list[j] = list[j], list[i]
		i++
		j--
	}
}

func main() {
        var i []interface{}
        i = append(i, "jeffotoni")
        i = append(i, " ano de 2020 ")
        i = append(i, []string{"otoni", "jeff", "Go"})
	i = append(i, []int{2020, 2012, 2009})
        Print(i)
 
	s := []string{"otoni", "jeff", "Go"}
	Reverse(s)
	Print(s)
	
	intt := []int{2020, 2012, 2009}
	Reverse(intt)
	Print(intt)
}
```

# Composição não herança

A abordagem adotada por **Go** foge da regra e **é incomum** para ***programação orientada a objetos****,* permitindo métodos em qualquer tipo, não apenas classes, mas sem qualquer forma de herança baseada em tipos, como subclasses. Isso significa que não há hierarquia de tipos. Isto não é um bug, não é uma desvantagem ou erro, é uma escolha intencional de design dos desenvolvedores de **Go**. Embora as hierarquias de tipos tenham sido usadas para construir softwares bem-sucedidos, é uma postura e opinião da equipe de desenvolvedores do **Go,** onde preferiram dar um passo para trás ao invés de fazerem igual a todos, o mesmo modelo repetitivo em diversas linguagens.

## Interfaces são implícitas

Em vez disso, o **Go** possui **interfaces,** que são apenas um conjunto de métodos e nada mais.  
*Exemplo:*

```go
type Gemetric interface {
  area() float64
  perim() float64
}
```

Todos os tipos de dados que implementam esses métodos satisfazem essa interface **implicitamente,** não há ***implements*** na declaração. A satisfação da interface é verificada estaticamente em tempo de compilação, portanto, apesar das interfaces de desacoplamento, elas são seguras quanto ao tipo.

Um tipo geralmente satisfaz muitas interfaces, cada uma correspondendo a um subconjunto de seus métodos. Essa fluidez de satisfação de interface incentiva uma abordagem diferente para a construção de software uma quebra no paradigma existente.

## Por que as interfaces não são explícitas ?

A programação orientada a objetos fornece uma visão poderosa: que o *comportamento* dos dados pode ser generalizado independentemente da *representação* desses dados. O modelo funciona melhor quando o comportamento (conjunto de métodos) é fixo, mas depois que você insere uma subclasse em um tipo e adiciona um método, *os comportamentos não são mais idênticos* . Se, em vez disso, o conjunto de comportamentos for fixo, como nas interfaces definidas estaticamente em Go, a uniformidade de comportamento permite que dados e programas sejam compostos uniformemente, ortogonalmente e com segurança.  
As hierarquias de tipo resultam em código frágil. **Go** estimula a *composição* e não herança, usando interfaces simples, geralmente de um método, para definir comportamentos triviais que servem como limites claros e compreensíveis entre os componentes e a eliminação da hierarquia de tipos também elimina uma forma de hierarquia de dependência.  
Os designs não são como métodos hierárquicos **herdados de subtipo**. Eles são mais **soltos, orgânicos, desacoplados, independentes** e portanto **escaláveis.**

```go
package main

import "fmt"
import "math"

type Gemetric interface {
    area() float64
    perim() float64
}

type rect struct {
    width, height float64
}

type circle struct {
    radius float64
}

func (r rect) area() float64 {
    return r.width * r.height
}

func (r rect) perim() float64 {
    return 2*r.width + 2*r.height
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

func (c circle) perim() float64 {
    return 2 * math.Pi * c.radius
}

func measure(g geometry) {
    fmt.Println(g)
    fmt.Println(g.area())
    fmt.Println(g.perim())
}

func main() {
    r := rect{width: 3, height: 4}
    c := circle{radius: 5}

    measure(r)
    measure(c)
}
```

# **Duck typing**

O Go suporta **“Duck typing”,** é um estilo de tipagem em que os [*métodos*](https://pt.wikipedia.org/wiki/M%C3%A9todo_(programa%C3%A7%C3%A3o)) *e propriedades* de um objeto determinam a semântica válida, em vez de sua [herança](https://pt.wikipedia.org/wiki/Heran%C3%A7a) de uma classe particular ou implementação de uma interface explicita. O nome do conceito refere-se ao [teste do pato](https://pt.wikipedia.org/wiki/Teste_do_pato), atribuído à [James Whitcomb Riley](https://pt.wikipedia.org/w/index.php?title=James_Whitcomb_Riley&action=edit&redlink=1). Isso faz com que o Go se pareça com uma linguagem dinâmica.

[Go](https://en.wikipedia.org/wiki/Go_(programming_language)) usa **“Tipagem Estrutural“** em métodos para determinar a compatibilidade de um tipo com uma interface. Não há hierarquias de tipos e a **“Tipagem Estrutural”** é uma alternativa interessante à herança clássica em linguagens com tipagem estática. Ele permite que você escreva algoritmos genéricos sem obscurecer a definição de um tipo em um mar de interfaces. Talvez mais importante, ajuda as linguagens com tipagem estática a capturar a sensação e a produtividade das linguagens dinamicamente tipificadas.

**“Duck typing”** ocorre em tempo de execução e “**Tipagem Estrutural”** que ocorre em tempo de compilação. Go não da suporte a orientação a objetos como é implementado nas linguagens como C#, Java ou mesmo C ++, não possui herança e honestamente fico muito feliz com isto, mas oferece alguns recursos como ***composição e interfaces***.

```go
package main

import (
    "fmt"
)

type familia interface {
    dados() string
}

type pai struct {
    Nome  string
    Idade int
    Cpf   string `json:"campo-x"`
}

func (p pai) dados() string {
    return fmt.Sprintf("Nome: %s, Idade: %d", p.Nome, p.Idade)
}

type filho struct {
    pai
    email string
}

func (f filho) dados() string {
    return fmt.Sprintf("Nome: %s, Idade: %d, Email: %s", f.Nome, f.Idade, f.email)
}

func mostraDados(membro familia) {
    fmt.Println(membro.dados())
}
func main() {
    pai := new(pai)
    pai.Nome = "Jeff"
    pai.Idade = 50
    pai.Cpf = "00.xxx.xxx-xx"

    filho := new(filho)
    filho.Nome = "Arthur"
    filho.Idade = 20
    filho.email = "arthur@gmail.com"

    mostraDados(pai)
    mostraDados(filho)
 }
```

# Muito suporte a bibliotecas de terceiros

No cenário atual **Go** disparou como linguagem de programação e todos os grandes, médios e pequenos players existentes estão desenvolvendo suas libs, sdks, clients etc. na linguagem **Go.** Existe milhares de iniciativas e muitas bibliotecas de terceiros. Tudo colabora para que isto ocorra, a comunidade **Go** é muito forte, cresce a cada dia, tem uma curva de aceitação muito alta e com isto facilita sua entrada nas empresas e sua utilização pelos desenvolvedores.

O resultado disto é a disseminação em massa na internet com bibliotecas escritas em **Go.** Existe também bibliotecas que estão abandonadas, como em qualquer outra linguagem mas funcionais. Mas o número de bibliotecas escritas em **Go** é muito mas muito grande. Diversas empresas estão reescrevendo suas plataformas em **Go** isto é uma vertente que não para de crescer. E dia após dia o número de ferramentas para [**DevOps**](https://www.redhat.com/pt-br/topics/devops) cresce, e com isto a aceitação e o aumento de novos adeptos em Go cresce na cultura e comunidade [**DevOps**](https://pt.wikipedia.org/wiki/DevOps).

# Gerenciamento de dependências nativo

**Go** teve um momento de trevas e durante um bom tempo não teve um gerenciador de dependências oficial. Após algumas tentativas e diversos posts e discussões sobre o assunto. O protótipo inicial [**VGO**](https://research.swtch.com/vgo) foi anunciado em fevereiro de 2018. Em julho de 2018, o suporte para módulos com versão foi instalado no repositório principal. O Go 1.11 foi lançado em agosto de 2018.  
O Go 1.11 inclui suporte preliminar para módulos com versão, conforme proposto [aqui](https://research.swtch.com/vgo-intro) . Mesmo que alguns detalhes possam mudar, versões futuras suportarão módulos definidos usando Go 1.11 ou 1.12, os testes e utilização em massa que estamos atualmente fazendo usando “***go mod***” acreditamos que não tem volta, ficou simplesmente fantástico, mesmo sendo anunciado como um módulo experimental está muito simples e poderoso.

**Go** é uma linguagem muito nova e o que surpreende é que em muito pouco tempo já exista uma infinidade de bibliotecas disponíveis para diversas necessidades e inúmeros tipos especificados de problemas e não para de crescer.

```go
$ go mod init yourapp
$ go build
```

# **Não é mais obrigatório o $GOPATH**

Após a implementação do controle de versão o **VGO** em **Go**, temos a possibilidade agora de não precisar que nossos projetos estejam abaixo do $GOPATH, agora podemos criar nossos projetos em qualquer diretório fora do $GOPATH. Esta funcionalidade só é possível devido o controle de versão, quando usamos o ***“go mod”*** os nossos workspaces de projetos passam a ser controlados de uma nova forma, basta executar o comando *“go mod init yourapp”* é criado um arquivo ***“go.mod”*** nele irá conter a localização do seu path e a versão que ele encontra-se. Muito simples e lindo.  
Toda vez que formos executar nosso projeto Go podemos utilizar a variável ambiente *“GO111MODUL=yes|no”* para determinar se iremos utilizar o “go mod” ou não.

# Garbage collector (GC)

Os **GCs** são peças complexas de software, são décadas de pesquisas e implementações, diversas tentativas de cientistas da computação em fazer um GC melhorado e confiável. Não é uma tarefa simples, devido a isto existe uma corrente muito grande na internet descrevendo os prós e contras de um GC. O que temos que levar em consideração é que independente do resultado, se não tivermos um GC teríamos que construir um para resolver o problema de alocação.

Geralmente existem duas maneiras de alocar memória em **Go**: na pilha e o heap. Em geral os desenvolvedores estão familiarizados com a pilha basta escrever um programa recursivo e irá perceber um [estouro](https://stackoverflow.com/questions/26158/how-does-a-stack-overflow-occur-and-how-do-you-prevent-it) da [pilha](https://stackoverflow.com/questions/26158/how-does-a-stack-overflow-occur-and-how-do-you-prevent-it) caso não faça corretamente. O **heap**, por outro lado, é um pool de memória que pode ser usado para alocação dinâmica.

As alocações de pilha são ótimas porque elas só vivem durante a vida útil da função da qual fazem parte. As alocações de heap, no entanto, não serão desalocadas automaticamente quando saem do escopo. Para evitar que o heap fique desassociado, devemos desalocar explicitamente ou, no caso de linguagens de programação com gerenciamento de memória (como Go), confiar no coletor de lixo para localizar e excluir objetos que não são mais referenciados.

De um modo geral, em linguagens com um **GC**, quanto mais você puder armazenar na pilha, melhor, uma vez que essas alocações nunca são vistas pelo **GC**. Compiladores usam uma técnica chamada *análise de escape* para determinar se algo pode ser alocado na pilha ou deve ser colocado no heap.

Na prática, escrever programas que forcem o compilador a somente alocar na pilha pode ser muito limitante, e assim, no Go, nós aproveitamos seu maravilhoso GC para fazer o trabalho de manter nosso heap limpo.

Quer da uma conferida e aprofundar ainda mais no assunto entre neste link escrito por R*ichard L. Hudson* [https://blog.golang.org/ismmkeynote](https://blog.golang.org/ismmkeynote).

# Alguns tipos de aplicações implementadas em Go

**Go** é uma linguagem de uso geral. [Neste link](https://github.com/nouney/awesome-go) você conseguirá visualizar diversas aplicações implementadas em **Go** e suas respectivas categorias.

## Alguns tipos:

. Web backend *(com* [*diversos frameworks*](https://github.com/nouney/awesome-go#web-frameworks) *disponíveis)*  
. Web Assembly ([*um dos frameworks vugu*](https://github.com/vugu/vugu))  
. Microservices (*alguns frameworks:* [*Go Micro*](https://micro.mu/)*,* [*Go Kit*](https://gokit.io/)*,* [*Gizmo*](https://github.com/NYTimes/gizmo)*,* [*Kite*](https://github.com/koding/kite))  
. Fragments services (*Termo citado pelo @jeffotoni em um grupo de discussão de microservices*)  
. Lambdas (*FaaS* [*example*](https://www.alexedwards.net/blog/serverless-api-with-go-and-aws-lambda))  
. Client Server  
. Aplicações em terminal ([utilizando a lib tview](https://github.com/rivo/tview))  
. IoT ([*alguns frameworks*](https://github.com/nouney/awesome-go#iot-internet-of-things))  
. Boots ([*alguns aqui*](https://github.com/nouney/awesome-go#bot-building))  
. Aplicações Client que usam tecnologia Web  
. Desktop Usando Qt+QML, Lib Nativa Win ([*example Qt*](https://github.com/therecipe/qt)*,* [*widgets Qt*](https://therecipe.github.io/widgets_playground/)*,* [*Qml*](https://doc.qt.io/qt-5/qtqml-index.html))  
. Aplicações de Rede  
. Aplicações para protocolos  
. Aplicações [rEST](https://pt.wikipedia.org/wiki/REST),  
. Aplicações [SOAP](https://pt.wikipedia.org/wiki/SOAP)  
. Aplicações [GraphQL](https://pt.wikipedia.org/wiki/GraphQL)  
. Aplicações [RCP](https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto)  
. Aplicações [TCP](https://pt.wikipedia.org/wiki/Transmission_Control_Protocol)  
. Aplicações [gRPC](https://en.wikipedia.org/wiki/GRPC)  
. Aplicações [Websocket](https://en.wikipedia.org/wiki/WebSocket)  
. GopherJS ([*compiles Go to JavaScript*](https://github.com/gopherjs))