Eu moro em Tashkent e quando estava na universidade comecei a aprender Python para escrever bots. Bots são pão uzbeque, tudo é construído sobre eles. Por exemplo, ninguém faz pedidos de comida, tudo é apenas em mensageiros instantâneos.
Aprendi a linguagem de artigos da Internet - apenas peguei o framework e acrescentei mais, olhei onde as coisas caíam, constantemente resolvi problemas com leetcode. Escrevi horrível então, mas o que foi, foi. Eu adorei, mas quanto mais fundo eu ia, mais irritante se tornava a velocidade de execução, as limitações de simultaneidade e a digitação dinâmica.
Então decidi tentar Go.
Go é simples, legal e procurado
Fiquei atraído pela ideia deles de competição leve e gostei do fato de que você não precisava entender o zoológico assíncrono que existia em python. No começo eu escrevi algo em Go para mim, observei como a linguagem se comporta. Então, no trabalho, decidimos tentar um projeto simples. Obtivemos bons resultados - tanto em termos de velocidade de desenvolvimento quanto de execução.
, Go , , — , , , , . , Go , , , .
: « — ». , . - , .
- . , — .
, . , , , .
, . , Go , — , .
, , — . , , . , , .
. ,
leetcode .
, , . .
( , ) — . , . , .
package main
import (
"fmt"
)
// .
// ,
func intersection(a, b []int) []int {
counter := make(map[int]int)
var result []int
for _, elem := range a {
if _, ok := counter[elem]; !ok {
counter[elem] = 1
} else {
counter[elem] += 1
}
}
for _, elem := range b {
if count, ok := counter[elem]; ok && count > 0 {
counter[elem] -= 1
result = append(result, elem)
}
}
return result
}
func main() {
a := []int{23, 3, 1, 2}
b := []int{6, 2, 4, 23}
// [2, 23]
fmt.Printf("%v\n", intersection(a, b))
a = []int{1, 1, 1}
b = []int{1, 1, 1, 1}
// [1, 1, 1]
fmt.Printf("%v\n", intersection(a, b))
}
, , Go. . , .
N .
package main
import (
"fmt"
"math/rand"
"time"
)
func randNumsGenerator(n int) <-chan int {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
out := make(chan int)
go func() {
for i := 0; i < n; i++ {
out <- r.Intn(n)
}
close(out)
}()
return out
}
func main() {
for num := range randNumsGenerator(10) {
fmt.Println(num)
}
}
N
n chan int. , .
, :
for num := range joinChannels(a, b, c) {
fmt.Println(num)
}
, , , , .
, . , , .
, . , wait group.
package main
import (
"fmt"
"sync"
)
func joinChannels(chs ...<-chan int) <-chan int {
mergedCh := make(chan int)
go func() {
wg := &sync.WaitGroup{}
wg.Add(len(chs))
for _, ch := range chs {
go func(ch <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for id := range ch {
mergedCh <- id
}
}(ch, wg)
}
wg.Wait()
close(mergedCh)
}()
return mergedCh
}
func main() {
a := make(chan int)
b := make(chan int)
c := make(chan int)
go func() {
for _, num := range []int{1, 2, 3} {
a <- num
}
close(a)
}()
go func() {
for _, num := range []int{20, 10, 30} {
b <- num
}
close(b)
}()
go func() {
for _, num := range []int{300, 200, 100} {
c <- num
}
close(c)
}()
for num := range joinChannels(a, b, c) {
fmt.Println(num)
}
}
. . , , - (, ) .
, https://blog.golang.org/pipelines.
— . . . — , .
package main
import (
"fmt"
)
func main() {
naturals := make(chan int)
squares := make(chan int)
go func() {
for x := 0; x <= 10; x++ {
naturals <- x
}
close(naturals)
}()
go func() {
for x := range naturals {
squares <- x * x
}
close(squares)
}()
for x := range squares {
fmt.Println(x)
}
}
WorkerPool
, .
— , . . , , .
package main
import (
"fmt"
)
func worker(id int, f func(int) int, jobs <-chan int, results chan<- int) {
for j := range jobs {
results <- f(j)
}
}
func main() {
const numJobs = 5
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
multiplier := func(x int) int {
return x * 10
}
for w := 1; w <= 3; w++ {
go worker(w, multiplier, jobs, results)
}
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
for i := 1; i <= numJobs; i++ {
fmt.Println(<-results)
}
}
waitGroup
. , .
, . . . , — .
package main
import (
"fmt"
)
type sema chan struct{}
func New(n int) sema {
return make(sema, n)
}
func (s sema) Inc(k int) {
for i := 0; i < k; i++ {
s <- struct{}{}
}
}
func (s sema) Dec(k int) {
for i := 0; i < k; i++ {
<-s
}
}
func main() {
numbers := []int{1, 2, 3, 4, 5}
n := len(numbers)
sem := New(n)
for _, num := range numbers {
go func(n int) {
fmt.Println(n)
sem.Inc(1)
}(num)
}
sem.Dec(n)
}
, — Rebrain — Go. , .
Go
, , Go . — , . — , , .
, , .
Go — , , , .
Go . ( «» — Go), , , , , . — Java C#. , , , , , .
++. , , ++ . , — .
Go . — , , . - - , .
— @alisher_m, Rebrain. , . , , .