Hola mundo en Go

1

Introducción al Curso de Golang

2

¬ŅQu√© es, por qu√© y quienes utilizan Go?

3

Instalar Go en Linux

4

Instalar Go en Mac

5

Instalar Go en Windows

6

Nuestras primeras líneas de código con Go

Variables, funciones y documentación

7

Variables, constantes y zero values

8

Operadores aritméticos

9

Tipos de datos primitivos

10

Paquete fmt: algo m√°s que imprimir en consola

11

Uso de funciones

12

Go doc: La forma de ver documentación

Estructuras de control de flujo y condicionales

13

El poder de los ciclos en Golang: for, for while y for forever

14

Operadores lógicos y de comparación

15

El condicional if

16

M√ļltiple condiciones anidadas con Switch

17

El uso de los keywords defer, break y continue

Estructuras de datos b√°sicas

18

Arrays y Slices

19

Recorrido de Slices con Range

20

Llave valor con Maps

21

Structs: La forma de hacer clases en Go

22

Modificadores de acceso en funciones y Structs

Métodos e interfaces

23

Structs y Punteros

24

Stringers: personalizar el output de Structs

25

Interfaces y listas de interfaces

Concurrencia y Channels

26

¬ŅQu√© es la concurrencia?

27

Primer contacto con las Goroutines

28

Channels: La forma de organizar las goroutines

29

Range, Close y Select en channels

Manejo de paquetes y Go Modules

30

Go get: El manejador de paquetes

31

Go modules: Ir m√°s all√° del GoPath con Echo

32

Modificando módulos con Go

Despedida del curso

33

Despedida

Bonus

34

Cheat Sheet Go

35

Librerías para desarrollo web con Go

36

Data Science con Go

No tienes acceso a esta clase

¬°Contin√ļa aprendiendo! √önete y comienza a potenciar tu carrera

Range, Close y Select en channels

29/36
Recursos

Aportes 14

Preguntas 11

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

  • Estoy trabajando en un proyecto donde se reciben datos del estado de una m√°quina vending(cantidad de productos, temperatura, etc), se debe guardar y analizar los datos para detectar posibles fallas. Go ser√≠a muy √ļtil en el procesamiento de muchas m√°quinas.
package main

import "fmt"

func message(text string, c chan string) {
	c <- text
}

func main() {
	c := make(chan string, 2)

	c <- "Mensaje 1"
	c <- "Mensaje 2"

	fmt.Println(len(c), cap(c))

	// Range y close
	close(c)
	//c<-"Mensaje 3"

	for message := range c {
		fmt.Println(message)
	}

	// Select
	email1 := make(chan string)
	email2 := make(chan string)

	go message("mensaje 1", email1)
	go message("mensaje 2", email2)

	for i := 0; i < 2; i++ {
		select {
		case m1 := <-email1:
			fmt.Println("Email recibido de email 1", m1)
		case m2 := <-email2:
			fmt.Println("Email recibido de email 2", m2)
		}
	}
}

Hola, vengo a compartir como yo hice el close de mi channel; basicamente comparo si el tama√Īo de mi channel es mayor o igual la capacidad de este, de ser as√≠ se cierra. Lo comparto por que creo que as√≠ ser√≠a en un proyecto de la vida real, pero no se, si tu ya has trabajado con channels en tu trabajo, de ser as√≠ por favor comentame si estoy siendo acertado con mi c√≥digo o no.

if len(c) >= cap(c) {
	close(c)
	fmt.Println("channel closed")
}

A continuaci√≥n dejo un ejemplo extra√≠do de https://tour.golang.org/concurrency/5 al cual le he a√Īadido comentarios explicando lo que sucede. Este ejemplo me ha ayudado a entender mejor como funciona el ‚Äúgo‚ÄĚ y ‚Äúselect‚ÄĚ.

package main

import "fmt"

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)

	// go func()... se lanza de manera concurrente:
	// la línea fmt.Println(<-c) queda en espera hasta que haya algo que leer de <-c.
	// Al ser lanzado concurrentemente, mientras dicha línea espera, se va a la ejecución de fibonacci(c, quit),
	// que guardará valores en c <- x tantas veces se produzca la espera de la línea fmt.Println(<-c).
	// Una vez sale del bucle, pasa a esperar case <-quit, que ser√° satisfecho con quit <- 0, por lo que imprimir√° "quit" y finalizar√°
	// el programa.
	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c)
		}
		quit <- 0
	}()
	fibonacci(c, quit)
}

Les comparto este ejercicio de concurrencia tomado del Tour de Go. Consiste en comparar dos √°rboles para saber si contienen los mismos elementos. En este ejercicio, hago los recorridos en forma concurrente utilizando channels.

La idea es recibir los nodos de los arboles en canales y luego ordenar los nodos para compararlos uno a uno.

package main

import (
	"container/list"
	"fmt"
	"golang.org/x/tour/tree"
	"sort"
)

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
	fmt.Println("Walking", t)
	queue := list.New()
	queue.PushBack(t)
	for queue.Len() > 0 {
		current := queue.Back()
		queue.Remove(current)
		var currentTree = current.Value.(*tree.Tree)

		ch <- currentTree.Value

		if currentTree.Left != nil {
			queue.PushBack(currentTree.Left)
		}

		if currentTree.Right != nil {
			queue.PushBack(currentTree.Right)
		}
	}
	fmt.Println("Finished Walking", t)
}

// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
	chan1 := make(chan int, 10)
	chan2 := make(chan int, 10)
	defer close(chan1)
	defer close(chan2)

	go Walk(t1, chan1)
	go Walk(t2, chan2)

	arr1 := make([]int, 10)
	arr2 := make([]int, 10)

	for i := 0; i < 10; i++ {
		arr1[i] = <-chan1
	}

	for i := 0; i < 10; i++ {
		arr2[i] = <-chan2
	}

	sort.Ints(arr1)
	sort.Ints(arr2)

	for i := 0; i < 10; i++ {
		if arr1[i] != arr2[i] {
			return false
		}
	}

	return true
}

func main() {
	tree10 := tree.New(1)
	anotherTree10 := tree.New(1)
	tree20 := tree.New(2)

	fmt.Println(tree10, " == ", anotherTree10, " true ==", Same(tree10, anotherTree10))
	fmt.Println(tree10, " == ", tree20, "false ==", Same(tree10, tree20))
}

El codigo del programa con algunos apuntes:

package main

import ‚Äúfmt‚ÄĚ

//del ejemplo message SELECT
func message(text string, c chan string) {
c <- text
}

func main() {
//Maneja 2 datos a la vez
c := make(chan string, 2)
// Inserta 2 mensajes
c <- "Mensaje 1"
c <- ‚ÄúMensaje 2‚ÄĚ
// len: cuantos gorutines hay en un channel
// cap: cantidad maxima que puede almacenar ese channel
fmt.Println(len©, cap©)

// Range y close keywork
//CLOSE: le dice al runtime de GO que va a cerrar el canal una vez dejas de usarlo y no recibe ningun otro dato adicional
close(c)

//c<-"Mensaje 3"
//RANGE: Recorrer la lista, reccoriendo todos los mensajes que estan en ese chanel c
for message := range c {
	fmt.Println(message)
}

// Select: multiples canales sin saber  cual va primero
email1 := make(chan string)
email2 := make(chan string)

go message("mensaje 1", email1)
go message("mensaje 2", email2)
// tener presente la cantidad de channels a manejar para el ciclo, en este ejemplo 2
for i := 0; i < 2; i++ {
	select {
	case m1 := <-email1:
		fmt.Println("Email recibido de email 1", m1)
	case m2 := <-email2:
		fmt.Println("Email recibido de email 2", m2)
	}
}

}

Creé algo rudimentario de Observador - Observable:

package main

import (
	"fmt"
	"time"
)

func emisorA(output chan<- string) {
	for {
		output <- "Emisor: A"
		time.Sleep(time.Second * 1)
	}
}

func emisorB(output chan<- string) {
	for {
		output <- "Emisor: b"
		time.Sleep(time.Second * 3)
	}
}

func main() {
	canalA := make(chan string)
	canalB := make(chan string)

	go emisorA(canalA)
	go emisorB(canalB)

	for {
		select {
		case cA := <-canalA:
			fmt.Println(cA)
		case cB := <-canalB:
			fmt.Println(cB)
		}
	}

}

En mi trabajo insertamos varias bases de datos y y tenemos que esperar a que se incerte una para seguir con la otra me parece que esto podria ayudar

En un proyecto de mantos acuiferos distribuidos en una red multi conectada, no me interesa tener los datos secuenciales del flujo de presion y gasto que hay, si se puede, cada segundo.
Me gustaria poder usar coroutines para poder tener una medicion precisa y exacta de este dato, sin la necesidad de esperar a que la medicion en alguna otra locacion termine o concluya su ciclo.

Un aporte para terminar de entender la concurrencia en go

golang

ūüėé

Una clase muy interesante

Buena recomendacion sobre cerrar el channel

len() y cap()