Vivo en Tashkent, y cuando estaba en la universidad comencé a aprender Python para escribir bots. Los bots son pan uzbeko, todo se basa en ellos. Por ejemplo, nadie hace solicitudes para pedir comida, todo es solo en mensajería instantánea.
Aprendí el idioma de artículos de Internet; simplemente tomé el marco y agregué más, miré dónde caían las cosas, resolví constantemente problemas con leetcode. Entonces escribí horriblemente, pero lo que fue, fue. Me encantó, pero cuanto más profundo fui, más molestas se volvieron la velocidad de ejecución, las limitaciones de concurrencia y la escritura dinámica.
Entonces decidí probar Go.
Go es simple, genial y muy solicitado
Me atrajo su idea de la competencia liviana y me gustó el hecho de que no era necesario comprender el zoológico asincrónico que estaba en Python. Al principio escribí algo en Go para mí, observé cómo se comportaba el idioma. Luego, en el trabajo, decidimos probar un proyecto simple. Obtuvimos buenos resultados, tanto en términos de velocidad de desarrollo como de ejecución.
, 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. , . , , .