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

Structs y Punteros

23/36
Recursos

Aportes 37

Preguntas 1

Ordenar por:

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

Eso de los punteros es una herencia directa del lenguaje C, y si mal no recuerdo es ya una norma en los leguajes compilados.

Quiero compartir con ustedes este video
CS50 2020 - Lecture 4 - Memory

All√≠ explican por qu√© lucen algo como 0xc0000b8010 spoiler est√° en hexadecimal el n√ļmero y el 0x es un prefijo en la computaci√≥n cuando se escribe un n√ļmero hexadecimal.

Reto:
Decidí dejar las variables del struct privadas y acceder a ellas mediante un get y set. Ya que hice uso de variables privadas cree un tipo de constructor.

package reto

import "fmt"

type Pc struct {
	ram   int
	disk  int
	brand string
}

func New(rm, dsk int, brn string) Pc {
	myPc := Pc{ram: rm, disk: dsk, brand: brn}
	return myPc
}

func (myPc Pc) FormatPrint() {
	fmt.Printf("Esta pc marca %s cuenta con una ram de %dGB y un disco de %dGB.\n", myPc.brand, myPc.ram, myPc.disk)
}

func (myPc *Pc) DuplicateRAM() {
	myPc.ram = myPc.ram * 2
}

func (myPc Pc) GetRam() int {
	return myPc.ram
}

func (myPc *Pc) SetRam(rm int) {
	myPc.ram = rm
}
package main

import (
	rt "curso-golang/src/16.Punteros/reto"
	"fmt"
)

func main() {
	myPc := rt.New(12, 200, "HP")
	myPc.SetRam(16)
	myPc.FormatPrint()
	fmt.Println("Se duplica la ram")
	myPc.DuplicateRAM()
	myPc.FormatPrint()
}
  • El s√≠mbolo " & " accede a la memoria de la variable.
  • El s√≠mbolo " * " accede al valor que est√° guardado en memoria, usando la direcci√≥n de memoria de la variable.

Lo que pude entender:

  • Podemos asociar una funci√≥n o m√©todo a un struct.
  • Si no indicamos el apuntador, es posible acceder a los valores de las variables, pero no es posible modificarlos desde el m√©todo.
  • Si pasamos el apuntador al m√©todo, entonces tendremos acceso a la memoria donde podremos modificar los valores.

Para solucionar el reto, cre√© una carpeta llamada ‚Äúpcpackage‚ÄĚ y dentro, un archivo llamado ‚Äúpcpackage.go‚ÄĚ. All√≠, escrib√≠ el siguiente c√≥digo:

package pcpackage

import "fmt"

// PC struct with public access
type PC struct {
	Ram   int
	Disk  int
	Brand string
}

func (myComputer *PC) DuplicateRAM() {
	myComputer.Ram = myComputer.Ram * 2
	fmt.Println(myComputer)
}

Luego, en el main.go para acceder al struct creado en pcpackage, escribí el siguiente código:

package main

import (
	computer "curso_golang_platzi/src/pcpackage"
	"fmt"
)

func main() {
	var newComputer computer.PC
	newComputer.Ram = 32
	newComputer.Disk = 256
	newComputer.Brand = "Razer"

	fmt.Println(newComputer)
	newComputer.DuplicateRAM()

	// Output:
	// {32 256 Razer}
	// &{64 256 Razer}
}
}```

Espero que sea de utilidad :)

Mi reto:

Un ejemplo para complementar el uso de Pointer receivers
https://tour.golang.org/methods/4

Creo que en esta clase falto mas detalle de lo que sucede con las funciones y la sintaxis de golang para associarlas con los structs. Por favor revisar lo que son las Receiver Functions, los value receivers y los pointer receivers. En resumen es lo que el intento demostrar el final del video pero sin esta terminologia la explicacion esta desconectada de las definiciones de la sintaxis de go.

Ver los nombres de un strong con %+v

package main

import "fmt"

type Pc struct {
	RAM int
	Disco int
}

func (pc *Pc) dupicateRam()  {
	pc.RAM = pc.RAM * 2
}

func main() {
	var Mypc = Pc{
		RAM:   2,
		Disco: 120,
	}
	fmt.Printf("%+v\n", Mypc)
	Mypc.dupicateRam()
	fmt.Printf("%+v\n", Mypc)
	Mypc.dupicateRam()
	fmt.Printf("%+v\n", Mypc)
}

management / management.go

package mangement

type Pc struct {
	Ram   int
	Disk  int
	Brand string
}

func (myPc *Pc) DuplicateRam() {
	myPc.Ram = myPc.Ram * 2
}

main.go

package main

import (
	"fmt"
	"golang/fundamentos/mangement"
)

func main() {
myPc := mangement.Pc{Ram: 16, Disk: 200, Brand: "msi"}
	fmt.Println(myPc)
	myPc.DuplicateRam()
	fmt.Println(myPc)
}


Reto:
Hice esta clase en un paquete:

type DoctorPublic struct {
	Name       string
	Speciality string
	Age        int
}

Y le agregue estas funciones:

//Funcion de la clase
//ShowData Public Funcion publica
func (myDoctor DoctorPublic) ShowData() string {
	age := strconv.Itoa(myDoctor.Age)
	return "Name:" + myDoctor.Name + " Speciality:" + myDoctor.Speciality + " Age:" + age

}

//Funcion con un puntero
//ChangeAge funcion publica para cambiar un valor mediante puntero
func (myDoctor *DoctorPublic) ChangeAge(age int) {
	myDoctor.Age = age
}

En el main:

//Instanciando un objeto
myDoctor_dos := pk.DoctorPublic{Name: "Gaia", Speciality: "Oncologo", Age: 20}

//Cambia la edad mediante el puntero
myDoctor_dos.ChangeAge(40)

fmt.Println(myDoctor_dos.ShowData())

Repaso

ūüďĄ Un buen art√≠culo con ejemplo sobre los punteros, c√≥mo crearlos y usar los operadores de direcci√≥n (&) y desreferenciaci√≥n (*) https://ed.team/blog/que-son-los-punteros-en-go

Es increíble trabajar con punteros en GO, cuando me tocó aprenderlos en C era un dolor de cabeza

main.go

package main

import "curso_golang_platzi/src/pc"

func main() {myPc := pc.PC{Ram: 16, Disk: 1024, Brand: "MSI"}
	fmt.Println(myPc)
	myPc.Ping()

	fmt.Println(myPc)
	myPc.DuplicateRAM()

	fmt.Println(myPc)
	myPc.DuplicateRAM()
	fmt.Println(myPc)
}

pc.go

package pc

import "fmt"

// PC Datos para un PC
type PC struct {
	Ram   int
	Disk  int
	Brand string
}

func (this PC) Ping() {
	fmt.Println(this.Brand, "Pong")
}

func (this *PC) DuplicateRAM() {
	this.Ram = this.Ram * 2
}

los punteros son el acceso a la dirección de memoria.

Solución reto

package strucpc

import "fmt"

type Pc struct {
	brand string
	disk  int
	ram   int
}

func (pc *Pc) SetBrand(brand string) {
	pc.brand = brand
}

func (pc *Pc) SetDisk(disk int) {
	pc.disk = disk
}

func (pc *Pc) SetRam(ram int) {
	pc.ram = ram
}

func (pc Pc) Brand() string {
	return pc.brand
}

func (pc Pc) Disk() int {
	return pc.disk
}

func (pc Pc) Ram() int {
	return pc.ram
}

func (pc Pc) ToString() string {
	return fmt.Sprintf("Marca: %s \nDisco: %d\nRam: %d", pc.brand, pc.disk, pc.ram)
}

-----------------------------

package main

import (
	pkPc "curso_goland_platzi/strucsPunteros/src/strucpc"
	"fmt"
)

func main() {
//PC PRIVATE FOR METODS
	var myPcPrivate pkPc.Pc
	myPcPrivate.SetBrand("private marca")
	myPcPrivate.SetDisk(500)
	myPcPrivate.SetRam(16)

	fmt.Println(myPcPrivate.ToString())
}

Reto resuelto:

Modifiqué un poco la lógica del programa. Obvié la función de duplicado y en remplazo, iteré con un bucle for el valor de la ram haciendo que al final de cada vuelta de ciclo, el valor de dicha llave, tenga la misma dinámica de aumento como lo explicado en clase. Entonces:

// [...]
func main(){
  myPc.Ping() 
  for i := 0; i <= 3; i++{
    fmt.Println(myPc.Ram)
    myPc.Ram *= 2
  }
}

V√©ase tambi√©n el m√≥dulo utilizado. Este a su vez ha estado sujeto a algunos cambios como el archivo principal: Struct contiene Ram & Disk compactados en una sola l√≠nea junto al tipo de valor que en com√ļn tienen, y por supuesto, el nombre como valores del Struct est√°n con Letter case para asegurar su coherencia de estar para p√ļblico uso. La funci√≥n Ping() tiene la misma l√≥gica:

// [...]
// Pc   BD de una PC
type Pc struct {
	Ram, Disk int
	Brand     string
}

func(myPc Pc) Ping() {
  fmt.Println(myPc.Brand)
}

Nótese también los datos ingresados al struct:

 myPc := pkg.Pc{Ram: 16, Disk: 500, Brand: "XYR"}

Estos datos están en el código completo, exactamente por encima de myPc.Ping() ubicado en el prime recuadro de código. Para facilitar la lectura, omití dicha parte.

También podemos duplicar la ram de esta forma:

myPc.ram *= 2 

Clase en código:

package main

import "fmt"

func main() {
	fmt.Println("")
	fmt.Println("==================")
	fmt.Println("Structs y Punteros")
	fmt.Println("==================")
	fmt.Println()

	fmt.Println("Al crear una variable en realidad se crea una dirección de memoria en ella se guarda un valor:")
	fmt.Println("variable := 50")
	fmt.Println()

	variable := 50

	fmt.Println("Al crear un puntero podemos tener 'referencia' a esa dirección de memoria. Para ello se usa el caracter '&':")
	fmt.Println("punteroDeVariable := &variable")
	fmt.Println()

	punteroDeVariable := &variable

	fmt.Println("El valor de 'variable' es >>>", variable, "...por otro lado")
	fmt.Println("El valor de 'punteroDeVariable' es >>>", punteroDeVariable)
	fmt.Println()

	fmt.Println("Teniendo un puntero, para acceder a su información se usa el caracter '*' de la siguiente forma:")
	fmt.Println("var abc int = *punteroDeVariable")
	fmt.Println()

	var abc int = *punteroDeVariable

	fmt.Println("El valor de 'abc' es: ", abc)
	fmt.Println()

	fmt.Println("¬Ņque pasa si sumamos 123 a la variable 'abc' y que efecto tiene en la variable original?")
	fmt.Println()

	abc = abc + 123
	fmt.Println("abc = abc + 123 >>> resultado abc =", abc)
	fmt.Println("'variable' = ", variable)
	fmt.Println()

	*punteroDeVariable = *punteroDeVariable + 234

	fmt.Println("¬ŅQue pasa si sumamos 234 pero al puntero de la variable? Para ello le ponemos el * antes:")
	fmt.Println("*punteroDeVariable = *punteroDeVariable + 234")
	fmt.Println("'*punteroDeVariable' imprime >>>", *punteroDeVariable)
	fmt.Println("valor de 'variable' original =", variable)
	fmt.Println("modificando el valor con el puntero, se modifica el de la variable original.")
	fmt.Println()

	fmt.Println("________________________________________________________________________________________")
	fmt.Println()

	fmt.Println("En java las referencias (versión de punteros) se crean por Default para los objetos.")
	fmt.Println("En Java no aplica para los tipos primitivos y para los 'wrap' en clases de los tipos primitivos.")
	fmt.Println()

	fmt.Println("En Golang requiere hacer todo lo que se presenta en esta clase")
	fmt.Println("Se menciona que esto permite crear funciones mas personalizadas y ")
	fmt.Println("permite llevar funciones de una librería a otro paquete de forma eficiente")
	fmt.Println("________________________________________________________________________________________")
	fmt.Println()
	fmt.Println()

	objetoStruct := MayusculoStruct{brand: "pollito", disk: 256, ram: 16}

	fmt.Println("Se crea un struct llamado 'MayusculoStruct' ...por estar su nombre en may√ļscula:")
	fmt.Printf("%+v", objetoStruct)
	fmt.Println()
	fmt.Println()

	fmt.Println("Se llama una funci√≥n constru√≠da para el struct que aumenta el tama√Īo de memoria en el pero")
	fmt.Println("Al recibir el struct por 'valor' al final no tiene efecto en el objeto original.")
	fmt.Println()

	objetoStruct.func_structPorValor_noModificaAlFinal()

	fmt.Println()
	fmt.Println("Se imprime en el 'main()' el objeto original: ")
	fmt.Printf("%+v", objetoStruct)
	fmt.Println()
	fmt.Println()

	fmt.Println("Ahora se llamara la función que recibe el struct por referencia y al final si tiene efecto sobre el original")
	fmt.Println()

	objetoStruct.func_structPorReferencia_siModificaAlFinal()

	fmt.Println()
	fmt.Println("Se imprime en el 'main()' el objeto original: ")
	fmt.Printf("%+v", objetoStruct)
	fmt.Println()
	fmt.Println()
}

func (computadora MayusculoStruct) func_structPorValor_noModificaAlFinal() {
	fmt.Println("_______________________________________")
	fmt.Println("func_structPorValor_noModificaAlFinal()")
	fmt.Println()

	fmt.Println("computadora.ram = computadora.ram * 2")
	computadora.ram = computadora.ram * 2

	fmt.Println("Resultado del cambio:")
	fmt.Printf("%+v", computadora)
	fmt.Println()
	fmt.Println()

	fmt.Println("fin de - func_structPorValor_noModificaAlFinal")
	fmt.Println("______________________________________")

}

func (emputadora *MayusculoStruct) func_structPorReferencia_siModificaAlFinal() {
	fmt.Println("____________________________________________")
	fmt.Println("func_structPorReferencia_siModificaAlFinal()")
	fmt.Println()

	fmt.Println("computadora.ram = computadora.ram * 2")
	emputadora.ram = emputadora.ram * 2

	fmt.Println("Resultado del cambio:")
	fmt.Printf("%+v", emputadora)
	fmt.Println()
	fmt.Println()

	fmt.Println("fin de - func_structPorReferencia_siModificaAlFinal")
	fmt.Println("______________________________________")
}

type MayusculoStruct struct {
	ram   int
	disk  int
	brand string
}

Mi aporte

package mypackage

import "fmt"

// Clase para representar una computradora
type Pc struct {
	Ram   int
	Disk  int
	Brand string
}

func (myPC Pc) Ping() {
	fmt.Println(myPC.Brand, "Pong")
}

func (myPC *Pc) DuplicateRam() {
	myPC.Ram = myPC.Ram * 2
}


//  Clase Principal
package main

import (
	"fmt"
	"Training/src/mypackage"
)
func main(){
	
	var myPc mypackage.Pc
	myPc.Ram = 16
	myPc.Disk = 512
	myPc.Brand = "DELL"
	fmt.Println(myPc)
	myPc.Ping()
	myPc.DuplicateRam()
	fmt.Println(myPc)
}

Me dieron en mi kora de cuando estudiaba C y Java ‚Ě£ÔłŹ

ūüėé

Interesante

Reto
main

package main

import (
	pk "curso_golang_platzi/src/mypackage"
	f "fmt"
)

func main() {

	var myPC pk.PcPublic
	myPC.Brand = "asus"
	myPC.Ram = 16
	myPC.Disk = 512

	f.Println(myPC)
	myPC.DuplicateRam()

	f.Println(myPC)
	myPC.DuplicateRam()

	f.Println(myPC)
	myPC.Ping()
}

package

package mypackage

import "fmt"

type PcPublic struct {
	Brand string
	Ram int
	Disk int
}

func (myPC PcPublic) Ping() {
	fmt.Println(myPC.Brand,"Pong")
}

func (myPC *PcPublic) DuplicateRam() {
	myPC.Ram *= 2
}
package main

import (
	"fmt"

	pk "example.com/golang_basic/src/13.RetoPunteros/mypackage"
)

func main() {
	var myPc pk.PcPublic
	myPc.Ram = 16
	myPc.Disk = 240
	myPc.Brand = "Kingston"
	// myPc := PcPublic{ram: 16, disk: 200, brand: "MSI"} // Instanciar struct
	myPc.PingPublic()
	fmt.Println(myPc)

	myPc.DuplicateRAM()
	fmt.Println(myPc)

	myPc.DuplicateRAM()
	fmt.Println(myPc)

}




package mypackage

import ‚Äúfmt‚ÄĚ

// Creamos un struc llamado pc
type PcPublic struct {
Ram int
Disk int
Brand string
}

// output: brand, "Pong"
func (myPc PcPublic) PingPublic() {
fmt.Println(myPc.Brand, ‚ÄúPong‚ÄĚ)
}

func (myPc *PcPublic) DuplicateRAM() {
myPc.Ram = myPc.Ram * 2
}


EJECUCION:

- Se crea instancia ==>  PC {Marca:"msi", RAM:16, Disco:200}
- Se duplica la RAM ==>  PC {Marca:"msi", RAM:32, Disco:200}
- Se cambia el Disco ==>  PC {Marca:"msi", RAM:32, Disco:500}
- Se cambia la RAM ==>  PC {Marca:"msi", RAM:64, Disco:500} 

Increible

package main

import "fmt"

type pc struct {
	ram int
	disk int
	brand string
}

// Creat funcion a una estructura
func (myPc pc) ping() {
	fmt.Println(myPc.brand, "Pong")
}

func (myPc *pc) duplicateRAM() {
	myPc.ram = myPc.ram * 2
}

func main() {
	a := 50
	b := &a

	fmt.Println(a, &a, b, *b)

	*b = 100
	fmt.Println(a)


	myPc := pc{ram: 16, disk: 200, brand: "msi"}
	fmt.Println(myPc)
	myPc.ping()

	myPc.duplicateRAM()
	fmt.Println(myPc)
	
	myPc.duplicateRAM()
	fmt.Println(myPc)
	
}

CODIGO:

package main

import (
	"fmt"
	"golang-base/practices/src/pc"
)

func main() {
	var myPc = pc.New(16, 200, "msi")
	fmt.Println("- Se crea instancia ==> ", myPc.Sprintf())
	myPc.DuplicateRAM()
	fmt.Println("- Se duplica la RAM ==> ", myPc.Sprintf())
	myPc.SetDisk(500)
	fmt.Println("- Se cambia el Disco ==> ", myPc.Sprintf())
	myPc.SetRam(64)
	fmt.Println("- Se cambia la RAM ==> ", myPc.Sprintf())
} 

CODIGO:
Archivo ‚Äúpc.go‚ÄĚ:

package pc

import "fmt"

type Pc struct {
	ram int
	disk int
	brand string
}

func New(ram int, disk int, brand string) Pc {
	return Pc{ram, disk, brand}
}

func (pc *Pc) GetRam() int {
	return pc.ram
}

func (pc *Pc) SetRam(ram int) {
	pc.ram = ram
}

func (pc *Pc) GetDisk() int {
	return pc.disk
}

func (pc *Pc) SetDisk(disk int) {
	pc.disk = disk
}

func (pc *Pc) GetBrand() string {
	return pc.brand
}

func (pc *Pc) SetBrand(brand string) {
	pc.brand = brand
}

func (pc *Pc) DuplicateRAM() {
	pc.SetRam(pc.ram * 2)
}

func (pc *Pc) Println() {
	fmt.Printf("PC {Marca:\"%s\", RAM:%d, Disco:%d}\n", pc.brand, pc.ram, pc.disk)
}

func (pc *Pc) Sprintf() string {
	return fmt.Sprintf("PC {Marca:\"%s\", RAM:%d, Disco:%d}", pc.brand, pc.ram, pc.disk)
} 

Reto solucionado!!!

Codigo de la clase:

package main

import "fmt"

type pc struct {
	ram   int
	disk  int
	brand string
}

func (myPC pc) ping() {
	fmt.Println(myPC.brand, "Pong")
}

func (myPC *pc) duplicateRam() {
	myPC.ram = myPC.ram * 2
}

func (myPC *pc) duplicateDisk() {
	myPC.disk = myPC.disk * 2
}

func main() {
	var a int = 50
	b := &a

	fmt.Println(*b, b)

	*b = 100
	fmt.Println(a)

	myPC := pc{ram: 16, disk: 200, brand: "linux"}
	fmt.Println(myPC)

	myPC.ping()

	fmt.Println(myPC)
	myPC.duplicateRam()
	myPC.duplicateDisk()

	fmt.Println(myPC)

}

Esto esta mas documentado aquí.