No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Interfaces y listas de interfaces

25/36
Recursos

Aportes 47

Preguntas 7

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Vale aclara algo:

las funciones en Go se definen de la siguiente manera:

func  nameFunc() {
	// body de la funci贸n
}

El nombre de las funciones no se pueden repetir en un mismos paquete, pero que esta pasando con las func area que se definieron dos veces en esta clase?

Lo que esta sucediendo es que no son simplemente funciones, en Go se les conoce como Methods. Un m茅todo es una funci贸n con un argumento de receptor especial. que debe de ser de tipo struct o interface y se definen de la siguiente manera:

func (receiver type)  nameFunc() {
	// body del metodo
}

Una buena practica es nombrar a nuestro receptor con la primera letra del struct o interface a la que estamos haciendo referencia, por ejemplo:

type cuadrado struct {
	lado float32
}

func (c cuadrado) area() float32 {
	return c.lado * c.lado
}

Reto

package main

import (
	"fmt"
	"math"
	"reflect"
)

type figure2D interface {
	getArea() float64
}

type square struct {
	base float64
}

type rectangle struct {
	high  float64
	width float64
}

type trapezoid struct {
	baseA float64
	baseB float64
	high  float64
}

type circle struct {
	radio float64
}

func (s square) getArea() float64 {
	return s.base * s.base
}

func (r rectangle) getArea() float64 {
	return r.high * r.width
}

func (t trapezoid) getArea() float64 {
	return ((t.baseA + t.baseB) / 2) * t.high
}

func (c circle) getArea() float64 {
	return math.Pi * math.Pow(c.radio, 2)
}

func calculateArea(f figure2D) {
	fmt.Printf("Area of %s: %.2f\n", reflect.TypeOf(f).Name(), f.getArea())
}

func main() {
	mySquare := square{base: 5}
	myRectangle := rectangle{width: 4, high: 5}
	myTrapezoid := trapezoid{baseA: 18, baseB: 10, high: 5}
	myCircle := circle{radio: 4}
	calculateArea(mySquare)
	calculateArea(myRectangle)
	calculateArea(myTrapezoid)
	calculateArea(myCircle)
}
  • Si los structs que tenemos en el c贸digo tienen m茅todos que hacen algo en com煤n (C谩lculos, obtener data, etc), es posible ejecutar 茅stos m茅todos usando una interfaz, de esta forma evitamos hacer c贸digo por cada struct.

Una aclaracion sobre el doble corchete

myInterface := []{}{"hola", 12, true}

https://stackoverflow.com/questions/57149795/what-does-the-double-curly-brace-mean-in-interface/57150132

Si se les dificulto un poco el funcionamiento de las interfaces en Golang (ya que en Java o Python son m谩s como contratos, en donde cumplimos el implementar una funci贸n en una clase), espero que mi explicaci贸n les ayude

Tomo a las interfaces m谩s como herramientas para hacer par谩metros de Structs en funciones universales, me explico:

Creamos esta funci贸n para calcular el area de cuadrado

func (c cuadrado) area() float64{
	return c.base * c.base
}

Normalmente tendr铆amos que invocar el m茅todo del struct cada que queramos usar la funci贸n

myCuadrado := cuadrado{base:2}
myCuadrado.area()

Pero gracias a las interfaces, ahora podemos pasar el Struct myCuadrado como parametro y reutilizar una misma funcion en multiples Structs

//Creamos un Struct triangulo
type triangulo struct{
	base float64
	altura float64
}

//Instanciamos el struct triangulo
myTriangulo := triangulo{base: 2, altura: 4}

//Creamos la interface
type figuraGeometrica2d interface{
	area() float64
}

//Ahora tenemos una funci贸n que toma como parametro Structs
func calcularArea(f figuraGeometrica2d){
	fmt.Println("El area de tu figura es de: ", f.area)
}

Y ahora, gracias a la interface, podemos pasar a todo Struct que tenga un m茅todo area() como parametro de la funcion calcularArea

calcularArea(myCuadrado)
calcularArea(myTriangulo)

Si se les dificult贸 entender el concepto o uso de interface, espero haberles ayudado (:

Quiz谩 es bueno tener en cuenta que aqu铆 no se implementan interfaces explicitamente sino implicitamente, es por eso que solo con que el m茅todo se llame 谩rea se hace la asociaci贸n!

Salio con fritas鈥

Este es el principal

package main

import (
	cua "curso_golang_basico/src/12Interfaces/pkgcuadrado"
	inter "curso_golang_basico/src/12Interfaces/pkginterfaces"
	rec "curso_golang_basico/src/12Interfaces/pkgrectangulo"
	"fmt"
)

func main() {

	var micuadrado cua.Cuadrado
	micuadrado.CreaLado(4)

	var mirec rec.Rectangulo
	mirec.CreaRec(8, 3)

	fmt.Println(micuadrado)
	fmt.Println(mirec)

	// Sin interfaces
	fmt.Println("\nSin interfaces: ")
	fmt.Println("Area cuadrado: ", micuadrado.Area())
	fmt.Println("Area rectangulo: ", mirec.Area())

	// Con interfaces
	fmt.Println("\nCon interfaces")
	inter.Calcular(micuadrado)
	inter.Calcular(mirec)

}

Este es el package cuadrado (un subdir dentro del principal)

package pkgcuadrado

import "fmt"

type Cuadrado struct {
	lado int
}

func (c *Cuadrado) CreaLado(l int) {
	c.lado = l
}

func (c Cuadrado) String() string {
	return fmt.Sprintf("Cuadrado de lado = %d", c.lado)
}

func (c Cuadrado) Area() int {
	return c.lado * c.lado
}

Este es ahora el package rectangulo

package pkgrectangulo

import "fmt"

type Rectangulo struct {
	largo int
	ancho int
}

func (r *Rectangulo) CreaRec(l, a int) {
	r.largo = l
	r.ancho = a
}

func (r Rectangulo) String() string {
	return fmt.Sprintf("Rectangulo de largo = %d y ancho = %d", r.largo, r.ancho)
}

func (r Rectangulo) Area() int {
	return r.ancho * r.largo
}

Y finalmente poniendome creativo un package para las interfaces鈥

package pkginterfaces

import "fmt"

type figuras2D interface {
	Area() int
}

func Calcular(f figuras2D) {
	fmt.Println("Area: ", f.Area())
}

Y lo mejor de todo es que anda! 馃槂

Holas Osmandi, seria chevere que pudieras agregar a este video la importancia de las interfaces, teniendo en cuenta que hay personas que vienen sin saber POO.

Saludos.

Me gusta mucho la forma de declarar las listas de interfaces:

package main

import "fmt"

func main() {
	myInterface := []interface{}{"Hola", 121, 4.90}
	fmt.Println(myInterface...)
}

Mas documentado aqu铆.

Reto 馃コ

//Main
package main

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

func main() {

	myCuadrado := pk.Cuadrado{Base: 4}
	f.Println(myCuadrado)
	pk.Calcular(myCuadrado)

	myRectangulo := pk.Rectangulo{Base: 2, Altura: 4}
	f.Println(myRectangulo)
	pk.Calcular(myRectangulo)

	myCirculo := pk.Circulo{Radio: 5}
	f.Println(myCirculo)
	pk.Calcular(myCirculo)

}
//mypackage
package mypackage

import "fmt"

type Figuras2D interface {
	area() float64
}

type Cuadrado struct {
	Base float64
}

type Rectangulo struct {
	Base   float64
	Altura float64
}

type Circulo struct {
	Radio float64
}

func (c Cuadrado) area() float64 {
	return c.Base * c.Base
}

func (r Rectangulo) area() float64 {
	return r.Base * r.Altura
}

func (ci Circulo) area() float64 {
	return  (ci.Radio * ci.Radio) * 3.1415
}

func Calcular(f Figuras2D) {
	fmt.Println("脕rea:", f.area())
}


Reto:
main.go

package main

import (
	fg "curso-golang/src/18.Interfaces/figuras"
	"fmt"
)

type figuras2D interface {
	Area() float64
}

func calcular(f figuras2D) {
	fmt.Printf("Area: %v\n", f.Area())
}

func main() {
	miCuadrado := fg.NewCuadrado(2)
	miRectangulo := fg.NewRectangulo(2, 4)
	miCirculo := fg.NewCirculo(3.2)
	miTriangulo := fg.NewTriangulo(7.8, 2.9)

	calcular(miCuadrado)
	calcular(miRectangulo)
	calcular(miCirculo)
	calcular(miTriangulo)
}

cuadrado.go

package figuras

type cuadrado struct {
	base float64
}

func NewCuadrado(bs float64) cuadrado {
	return cuadrado{base: bs}
}

func (c cuadrado) Area() float64 {
	return c.base * c.base
}

rectangulo.go

package figuras

type rectangulo struct {
	base   float64
	altura float64
}

func NewRectangulo(bs, alt float64) rectangulo {
	return rectangulo{base: bs, altura: alt}
}

func (r rectangulo) Area() float64 {
	return r.altura * r.base
}

circulo.go

package figuras

import "math"

type circulo struct {
	radio float64
}

func NewCirculo(rd float64) circulo {
	return circulo{radio: rd}
}

func (c circulo) Area() float64 {
	return math.Pi * c.radio * c.radio
}

triangulo.go

package figuras

type triangulo struct {
	base   float64
	altura float64
}

func NewTriangulo(bs, alt float64) triangulo {
	return triangulo{base: bs, altura: alt}
}

func (t triangulo) Area() float64 {
	return t.base * t.altura / 2
}

Algo que no se menciona en el curso y puede generar duda es como la funci贸n calculate sabe que los structs que pasamos est谩n implementando la interfaz que estamos esperando. Esto pasa porque GO de forma impl铆cita implementa la interfaz cuando un struct tiene todos los m茅todos que esa interfaz necesita.

Adicional recuerden que en ese ejemplo se aplican algunos principios SOLID como: Interface segregation principle, Liskov substitution y Dependency inversion principle.

C贸digo para usar un poder especial de diferentes formas con diferentes pokemon. El resultado: la cantidad de poder que aumenta el pokemon.

package main

import "fmt"

type pokemonPwrs interface {
	usePwr() int
}

type myElecPokemon struct {
	name string
	volts int
	level int
}

type myFirePokemon struct {
	name string
	flames int
	level int
}

func (fPoke myFirePokemon) usePwr() int {
	return fPoke.flames * fPoke.level
}

func (ePoke myElecPokemon) usePwr() int {
	return ePoke.volts * ePoke.level
}

func  useSpecialPwrs(p pokemonPwrs) {
	fmt.Printf("Power: %v \n", p.usePwr())
}

func main() {
	var pikachu = myElecPokemon{name: "Pikachu", volts: 10, level: 3}
	var litten = myFirePokemon{name: "Litten", flames: 25, level:5}
	useSpecialPwrs(pikachu)
	useSpecialPwrs(litten)
}

yo diria que esta clase explica un poco de polimorfismo con las estructuras e interfaces

Reto completo

Archivo main

package main

import (
	mpk "curso_golang_basico/src/mypackage"
	"fmt"
)

func main() {
	//Entrada de valores
	myCuadrado := mpk.Cuadrado{Base: 2}
	myRectangulo := mpk.Rectangulo{Base: 3, Altura: 5}

	//Impresi贸n de valores
	fmt.Println(myCuadrado)
	fmt.Println(myRectangulo)

	//Calculo de valores
	mpk.Calcular(myCuadrado)
	mpk.Calcular(myRectangulo)

	//SALIDA
	// Un lado del cuadrado mide: 2 cm
	// La base del rectangulo mide: 3 cm y la altura del rectangulo mide: 5 cm
	// El 谩rea es: 4 cm2
	// El 谩rea es: 15 cm2

}

Archivo mypackage

package mypackage

import "fmt"

//PARTE 4.
type figura2D interface {
	Area() float64
}

//PARTE 1.
type Cuadrado struct {
	Base float64
}

//PARTE 1.
type Rectangulo struct {
	Base   float64
	Altura float64
}

//Parte 3.
func (c Cuadrado) Area() float64 {
	return c.Base * c.Base
}

//PARTE 3.
func (r Rectangulo) Area() float64 {
	return r.Base * r.Altura
}

//PARTE 5.
func Calcular(f figura2D) {
	fmt.Println("El 谩rea es:", f.Area(), "cm2")
}

//Para la impresi贸n del valor entrante de uncuadrado
func (C Cuadrado) String() string {
	return fmt.Sprintf("Un lado del cuadrado mide: %v cm", C.Base)
}

//Para la impresi贸n de los valores entrantes de un rectangulo
func (C Rectangulo) String() string {
	return fmt.Sprintf("La base del rectangulo mide: %v cm y la altura del rectangulo mide: %v cm", C.Base, C.Altura)
}

Recordando Java y ocultando los atributos del struct me puse a jugar con lo siguiente:

package main

import (
	cua "curso_golang_basico/src/12Interfaces/pkgcuadrado"
	"fmt"
)

func main() {

	var micuadrado cua.Cuadrado
	micuadrado.CreaLado(4)

	fmt.Println("Imprimo micuadrado: ", micuadrado)
}

Y en el package鈥

package pkgcuadrado

import "fmt"

type Cuadrado struct {
	lado int
}

func (c *Cuadrado) CreaLado(l int) {
	c.lado = l
}

func (c Cuadrado) String() string {
	return fmt.Sprintf("Cuadrado de lado = %d", c.lado)
}

De esta manera no hago publico informacion que no estaria bueno exponer 馃槂

package main

import (
	//pk es el alias
	pk "curso_golang_platzi/src/mypackage"
	"fmt"
)

func main() {

	myCuadrado := pk.Cuadrado{Base: 2}
	myRectangulo := pk.Rectangulo{Base: 2, Altura: 4}
	myCirculo := pk.Circulo{Radio: 5}
	myTrapecio := pk.Trapecio{Lado1: 5, Lado2: 7, Altura: 3}

	pk.Calcular(myCuadrado)
	pk.Calcular(myRectangulo)
	pk.Calcular(myCirculo)
	pk.Calcular(myTrapecio)

	//Lista de interfaces - para usar tipos diferentes en Slides

	myInterface := []interface{}{"Hola", 12, 4.90}
	fmt.Println(myInterface...)

}
 


package mypackage

import "fmt"

constfloat64 = 3.14159265

type figuras2D interface {
	area() float64
}

type Cuadrado struct {
	Base float64
}

type Rectangulo struct {
	Base   float64
	Altura float64
}

type Circulo struct {
	Radio float64
}

type Trapecio struct {
	Lado1  float64
	Lado2  float64
	Altura float64
}

func (c Cuadrado) area() float64 {
	return c.Base * c.Base
}

func (r Rectangulo) area() float64 {
	return r.Base * r.Altura
}

func (c Circulo) area() float64 {
	return (c.Radio * c.Radio) * 蟺
}

func (t Trapecio) area() float64 {
	return ((t.Lado1 + t.Lado2) / 2) * t.Altura
}

// Calcular - calcula 谩reas
func Calcular(f figuras2D) {
	fmt.Println("Area:", f.area())
}

// Se usa may煤sculas para indicar que es p煤blica PC con accesos p煤blico
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) String() string {

	return fmt.Sprintf("Tengo %d GB RAM, %d GB Disco y es una %s", myPC.Ram, myPC.Disk, myPC.Brand)
}


Reto solucionado

package main

import (
	"fmt"
	"math"
)

type calcularArea interface {
	area() float64
}

type cuadrado struct {
	Lado float64
}

func (c cuadrado) area() float64 {
	return c.Lado * c.Lado
}

type rectangulo struct {
	Base   float64
	Altura float64
}

func (c rectangulo) area() float64 {
	return c.Base * c.Altura
}

type circulo struct {
	radio float64
}

func (c circulo) area() float64 {
	return math.Pi * math.Pow(c.radio, 2)
}

type trapecio struct {
	baseMayor float64
	baseMenor float64
	altura    float64
}

func (t trapecio) area() float64 {
	return t.altura * ((t.baseMayor + t.baseMenor) / 2)
}

func hacerCalculo(f calcularArea) {
	fmt.Println(f.area())
}

func main() {
	miCuadrado := cuadrado{Lado: 7}
	miRectangulo := rectangulo{Base: 12, Altura: 5}
	miCirculo := circulo{radio: 5}
	miTrapecio := trapecio{baseMayor: 4, baseMenor: 3.5, altura: 2}

	hacerCalculo(miCuadrado)
	hacerCalculo(miRectangulo)
	hacerCalculo(miCirculo)
	hacerCalculo(miTrapecio)
}

Esto es un gran problema en Golang, lo acabo de ver. No sabemos que hace el c贸digo exactamente y no se puede auditar.

Reto

package main

import (
	figc "curso_golang_platzi/src/cuadrado"
	fig2d "curso_golang_platzi/src/figuras2d"
	figr "curso_golang_platzi/src/rectangulo"
	"fmt"
)

func calculate(f fig2d.Figuras2D) {
	fmt.Println("Area:", f.Area())
}

func main() {
	mySquare := figc.Cuadrado{}
	mySquare.ColocarBase(2)
	myRectangle := figr.Rectangulo{}
	myRectangle.ColocarBase(2)
	myRectangle.ColocarAltura(3)

	calculate(mySquare)
	calculate(myRectangle)
}
package cuadrado

type Cuadrado struct {
	base float64
}

func (c Cuadrado) Area() float64 {
	return c.base * c.base
}

func (c *Cuadrado) ColocarBase(base float64) {
	c.base = base
}
package rectangulo

type Rectangulo struct {
	base   float64
	altura float64
}

func (r Rectangulo) Area() float64 {
	return r.base * r.altura
}

func (c *Rectangulo) ColocarBase(base float64) {
	c.base = base
}

func (c *Rectangulo) ColocarAltura(altura float64) {
	c.altura = altura
}
package figuras2d

type Figuras2D interface {
	Area() float64
}

Una Interface tan s贸lo es un m茅todo que lo comparten varios Structs

El reto si ven algo que se pueda mejorar por favor me lo indican para entender mejor el tema. Muchas gracias !

package main

import (
	"fmt"
	"math"
)

type figuras2D interface{
	area() float64
}

type cuadrado struct{
	base float64
}
type rectangulo struct{
	base float64
	altura float64
}
type circulo struct{
	radio float64	
}
type trapecio struct{
	base1 float64
	base2 float64
	altura float64	
}

func (c cuadrado) area() float64{
	return c.base * c.base
}
func(r rectangulo) area() float64{
	return r.base * r.altura
}
func(ci circulo) area() float64{
	return (math.Pi * (ci.radio * ci.radio))
}
func(t trapecio) area() float64{
	return (((t.base1 + t.base2) / 2) * t.altura)
}
func calculador (f figuras2D){
	fmt.Println("Area: ", f.area())
}


func main() {
	myCuadrado := cuadrado{base: 2}
	myRectangulo := rectangulo{base: 2, altura: 3}
	myCirculo := circulo{radio: 10}
	myTrapecio := trapecio{base1: 4, base2: 3, altura: 8}

	calculador(myCuadrado)
	calculador(myRectangulo)
	calculador(myCirculo)
	calculador(myTrapecio)
}

Resume Code

package main

import shapes "curso_golang_platzi/src/mypackage"

func main() {
	s1 := shapes.NewTriangle(5, 5)
	s2 := shapes.NewSquare(5)
	s3 := shapes.NewRectangle(2, 5)
	shapes.Calculate(s1)
	shapes.Calculate(s2)
	shapes.Calculate(s3)
}
package mypackage

import "fmt"

//The interface is used for repetitive methods
type shape interface {
	Area() float64
}

type square struct {
	side float64
}

type rectangle struct {
	side float64
	base float64
}

type triangle struct {
	base   float64
	height float64
}

func NewTriangle(base float64, height float64) *triangle {
	t := new(triangle)
	t.base = base
	t.height = height
	return t
}

func (t triangle) Area() float64 {
	return (t.base * t.height) / 2
}

func (t triangle) GetBase() float64 {
	return t.base
}

func (t *triangle) SetBase(base float64) {
	t.base = base
}

func (t triangle) GetHeight() float64 {
	return t.height
}

func (t *triangle) SetHeight(height float64) {
	t.height = height
}

func (t triangle) String() string {
	return fmt.Sprintf("Base: %f\nHeight: %f\n\n", t.base, t.height)
}

func NewRectangle(base float64, side float64) *rectangle {
	r := new(rectangle)
	r.base = base
	r.side = side
	return r
}

func (r rectangle) Area() float64 {
	return r.base * r.side
}

func (r rectangle) GetBase() float64 {
	return r.base
}

func (r *rectangle) SetBase(base float64) {
	r.base = base
}

func (r rectangle) GetSide() float64 {
	return r.side
}

func (r *rectangle) SetSide(side float64) {
	r.side = side
}

func (r rectangle) String() string {
	return fmt.Sprintf("Side: %f\nBase: %f\n\n", r.side, r.base)
}

func NewSquare(side float64) *square {
	s := new(square)
	s.side = side
	return s
}

func (s square) Area() float64 {
	return s.side * s.side
}

func (s square) GetSide() float64 {
	return s.side
}

func (s *square) SetSide(side float64) {
	s.side = side
}

func (s square) String() string {
	return fmt.Sprintf("Base: %f\n\n", s.side)
}

//Function of the interface
func Calculate(s shape) {
	fmt.Print(s)
	fmt.Printf("Area: %f\n\n", s.Area())
}

func mypackage() {

}

Buenas muchach@s 馃憢
Paso mis apuntes con otro ejemplo:

package main

import (
	"fmt"
	"math"
)

type BH struct {
	Base   float32
	Altura float32
}

type Rectangulo struct {
	BH
}

type Triangulo struct {
	L1 float32
	L2 float32
	L3 float32
	BH
}
type Cuadrado struct {
	Lado float32
}

type Shape interface {
	Area() float32
	Perimeter() float32
	String() string
}

func (r *Rectangulo) Area() float32 {
	return r.Altura * r.Base
}
func (r *Rectangulo) Perimeter() float32 {
	return 2*r.Altura + 2*r.Base
}

func (r *Rectangulo) String() string {
	return fmt.Sprintf("Area: %v  | Perimetro: %v", r.Area(), r.Perimeter())

}

func (c *Cuadrado) Perimeter() float32 {
	return 4 * c.Lado
}

func (c *Cuadrado) Area() float32 {
	return float32(math.Pow(float64(c.Lado), 2))

}

func (c *Cuadrado) String() string {
	return fmt.Sprintf("Area: %v  | Perimetro: %v", c.Area(), c.Perimeter())

}
func (t *Triangulo) Perimeter() float32 {
	return t.L1 + t.L2 + t.L3
}

func (t *Triangulo) Area() float32 {
	return t.Base * t.Altura
}
func (t *Triangulo) String() string {
	return fmt.Sprintf("Area: %v  | Perimetro: %v", t.Area(), t.Perimeter())

}

func Inprimir(s Shape) {
	fmt.Println(s.String())
}

func main() {

	var cuadrado = Cuadrado{Lado: 5}

	var triangulo = Triangulo{L1: 5, L2: 3, L3: 6, BH: (BH{Base: 10, Altura: 10})}
	Inprimir(&cuadrado)
	Inprimir(&triangulo)

}

Este concepto es extremadamente poderoso para implementar. Es un poco distinto a Python y me encanta como dos approaches distintos muestran sus potencialidades. En este sentido, cada struct con sus funciones deber铆a ir en un archivo por separado verdad? Para mantener el orden

figures/figures.go

package figures

import "fmt"

type figuras2D interface {
	area() float64
}

type Cuadrado struct {
	base float64
}

type Rectangulo struct {
	base   float64
	altura float64
}

func (c Cuadrado) area() float64 {
	return c.base * c.base
}

func (r Rectangulo) area() float64 {
	return r.altura * r.base
}

func Calcular(f figuras2D) {
	fmt.Println("Area:", f.area())
}

//setters & getters
func (c *Cuadrado) SetCuadradoBase(base float64) {
	c.base = base
}

func (c Cuadrado) GetCuadradoBase() float64 {
	return c.base
}

func (r *Rectangulo) SetRectanguloBase(base float64) {
	r.base = base
}

func (r Rectangulo) GetRectanguloBase() float64 {
	return r.base
}

func (r *Rectangulo) SetRectanguloAltura(altura float64) {
	r.altura = altura
}

func (r Rectangulo) GetRectanguloAltura() float64 {
	return r.altura
}

main.go

import (
	"golang/fundamentos/figures"
)
func main() {
	mycuadrado := figures.Cuadrado{}
	mycuadrado.SetCuadradoBase(4)

	myrectangulo := figures.Rectangulo{}
	myrectangulo.SetRectanguloAltura(10)
	myrectangulo.SetRectanguloBase(2)

	figures.Calcular(mycuadrado)
	figures.Calcular(myrectangulo)

}

Ac谩 encuentran las clases 23, 24, 25
repo-cool-go

Recorriendo una lista de interfaces

interfaceLis := []interface{}{"Hello world", 4.5, 5, true}
	fmt.Println(interfaceLis)

	for i, v := range interfaceLis {
		fmt.Println(i, v)
	}

Me tomo un tiempo entender q es la lista de interfaces, este stackoverflow explica bien por q la repeticion de {}{}
https://stackoverflow.com/questions/57149795/what-does-the-double-curly-brace-mean-in-interface/57150132

Este feature de Go, te permite crear un slice indicando q INTERFACE pertenecen todos los items creados:

  // Slice de objetos de la interfaz figuras2D
	figuras := []figuras2D{cuadrado{base: 2}, rectangulo{base: 2, altura: 4}}
	for _, figura := range figuras {
		fmt.Println(figura)
		calcular(figura)
	}

Y al intentar colocar un objeto q no tiene la implementacion de esa interfaz, pues el editor y al correr te indicaran q no implementa lo q indica la interfaz.
Ese feature realmente me gusto

// Agregando un STRING en el slice
	figuras := []figuras2D{cuadrado{base: 2}, rectangulo{base: 2, altura: 4}, "invalid object"}

// Al ejecutarlo
PS C:\git\test-go> go run .\src\interfacesListas.go
# command-line-arguments
src\interfacesListas.go:55:76: cannot use "invalid object" (constant of type string) as type figuras2D in array or slice literal:
        string does not implement figuras2D (missing area method)

Mi soluci贸n al reto:

Paquete:

package mypackage

import (
	"fmt"
)
// trapecio para reto

type Trapecio struct {
	Altura     float64
	Base_menor float64
	Base_mayor float64
	//area
	sum   float64
	mitad float64
}

// sacar area para el trapecio
//-declaraci贸n de variable para funci贸n
var T Trapecio

func (T *Trapecio) area() float64 {
	T.sum = T.Base_menor + T.Base_mayor
	T.mitad = T.sum / 2
	return T.mitad * T.Altura
}

//-striger para trapecio
func (T Trapecio) string() string {
	return fmt.Sprintf("El trapecio con altura %v, base menor %v y base mayor %v tiene area ", T.Altura, T.Base_menor, T.Base_mayor)
}
// circulo para el reto

type Circulo struct {
	Diametro float64
	//area
	radio          float64
	cuadrado_radio float64
	pi             float64
}

// sacar area al circulo
//-declaraci贸n de variable usada en la funci贸n
var C Circulo

func (C *Circulo) area() float64 {
	C.pi = 3.144142
	C.radio = C.Diametro / 2
	C.cuadrado_radio = C.radio * C.radio
	return C.pi * C.cuadrado_radio
}

//-stringer para circulo
func (C Circulo) string() string {
	return fmt.Sprintf("El circulo de diametro %v tiene area ", C.Diametro)
}
type figuras interface {
	area() float64
	string() string
}

func Cal(f figuras) {
	fmt.Print(f.string())
	fmt.Println(f.area())
}

Main:

package main

import (
	"golang/src/mypackage"
)

func main() {
	my_trapecio := mypackage.Trapecio{
		Base_menor: 3.5,
		Base_mayor: 9.5,
		Altura:     4,
	}
	my_circulo := mypackage.Circulo{
		Diametro: 4,
	}

	mypackage.Cal(&my_trapecio)
	mypackage.Cal(&my_circulo)
}

Me gustar铆a mucho una retroalimentaci贸n del profesor o una correcci贸n si lo amerita.

Aproveche de implementar String de tal forma que muestre el tipo de figura.

package geometry

import (
	"fmt"
	"math"
)

type Rectangle struct {
	Base, Height float64
}

func (rectangle Rectangle) Area() float64 {
	return rectangle.Base * rectangle.Height
}

func (rectangle Rectangle) String() string {
	return fmt.Sprintf("Rectangle{Base: %.2f, Height: %.2f}", rectangle.Base, rectangle.Height)
}

func (rectangle Rectangle) Diagonal() float64 {
	return math.Sqrt(math.Pow(rectangle.Base, 2) + math.Pow(rectangle.Height, 2))
}

En lenguajes tipicamente orientados a objetos como Java, la implementaci贸n de una interface se hace de manera explicita.

MyClase implements MyInterface

En Go esta implementaci贸n es impl铆cita

package main

import "fmt"

type I interface {
	M()
}

type T struct {
	S string
}

// El m茅todo M indica que el type T implementa la interface I,
// pero no se requiere una declaraci贸n expl铆cita
func (t T) M() {
	fmt.Println(t.S)
}

func main() {
	var i I = T{"hello"}
	i.M()
}


https://go.dev/tour/methods/10

Mi soluci贸n
Mi Package main:

package main

import (
	pb "curso_golang_go/Intefarces_Listas_de_interfaces/reto/metodos_y_structs_Publicos"
	"fmt"
)

type areas interface {
	Area1() float64
}

func calcularPrivado(f areas) {
	fmt.Println("El area es:", f.Area1())
}
func main() {
	var cuadradoPu pb.Cuadrado
	var rectanguloPu pb.Rectangulo
	var circuloPu pb.Circulo

	cuadradoPu.Base = 2
	rectanguloPu.Altura = 3
	rectanguloPu.Base = 3
	circuloPu.Pi = 3.14
	circuloPu.Radio = 4

	calcularPrivado(cuadradoPu)
	calcularPrivado(circuloPu)
	calcularPrivado(rectanguloPu)
}

Mi package Import:

package publicos

type Circulo struct {
	Pi    float64
	Radio float64
}

type Rectangulo struct {
	Base   float64
	Altura float64
}

type Cuadrado struct {
	Base float64
}

func (c Cuadrado) Area1() float64 {
	return c.Base * c.Base
}

func (r Rectangulo) Area1() float64 {
	return r.Altura * r.Base
}

func (ci Circulo) Area1() float64 {
	return ci.Pi * (ci.Radio * ci.Radio)
}

NOTA: Deje la Interfaz como privada pues cuando la dejaba publica me arrojaba error 驴Alguien sabe porque ?

:3
Brutal.

Mi solucion al reto:
En el Package:

//INTERFAZ
type Figure interface {
	Area() float64
}

//CLASES PARA LA INTERFAZ
type Rectangulo struct {
	Base   float64
	Altura float64
}

type Trapecio struct {
	Base      float64
	BaseMayor float64
	Altura    float64
}

type Circulo struct {
	Radio float64
}

//FUNCIONES DE LAS CLASES PARA LA INTERFAZ
func (r Rectangulo) Area() float64 {
	return r.Base * r.Altura
}

func (t Trapecio) Area() float64 {
	return ((t.Base + t.BaseMayor) * t.Altura) / 2
}

func (c Circulo) Area() float64 {
	const PI float64 = 3.14
	return PI * (math.Pow(c.Radio, 2))
}

//Funcion de la interfaz
func Calculate(f Figure) {
	fmt.Println("El area es: ", f.Area())
}

Clase Main:

//EJECUCION DE LA INTERFAZ EN MAIN
	myRectangulo := pk.Rectangulo{Base: 10, Altura: 5}
	myTrapecio := pk.Trapecio{Base: 5, BaseMayor: 10, Altura: 4}
	myCirculo := pk.Circulo{Radio: 7}

	pk.Calculate(myRectangulo)
	pk.Calculate(myTrapecio)
	pk.Calculate(myCirculo)

Podemos agregar interfaces a una interfaz:

// [...]
func main() {
   typeInte      := []interface{}{1,2,3}
   typeStri      := []interface{}{"a", "b", "c"}
   typeBool      := []interface{}{true, false}

   myInterface   := []interface{}{typeBool, typeStri, typeInte}
   fmt.Println(myInterface)

}

Otra forma de imprimir el area de cada Struct:

fmt.Println(figuras2D.area(myCuadrado))
fmt.Println(figuras2D.area(myRectangulo))

Uff!! OOP en Go 馃挋

Para quienes deseen ponerse un norte en este tema
Medium - Programaci贸n Orientada a Objetos

馃く

aqui les dejo mi aporte 馃槃

<
// Main

package main

import (
	pki "curso_golang_platzi/src/packageinterfaces"
	"fmt"
)

func main() {

	// Preguntar al ususario a que figura quiere calcular su area
	fmt.Println("Actualmente puedo calcular el area de las siguientes figuras")
	fmt.Println("Cuadrado, Rectangulo, Circulo, Triangulo")
	fmt.Println("Ingrese el nombre de la figura:")
	var figura string
	fmt.Scanf("%s", &figura)

	if figura == "Cuadrado" {
		fmt.Println("Ingrese el valor de la base:")
		var base float64
		fmt.Scanf("%f", &base)
		myCuadrado := pki.Cudrado{Base: base}
		pki.CalculaArea(myCuadrado)
	} else if figura == "Rectangulo" {
		fmt.Println("Ingrese el valor de la base:")
		var base float64
		fmt.Scanf("%f", &base)
		fmt.Println("Ingrese el valor de la altura:")
		var altura float64
		fmt.Scanf("%f", &altura)
		myRectangulo := pki.Rectangulo{Base: base, Altura: altura}
		pki.CalculaArea(myRectangulo)
	} else if figura == "Circulo" {
		fmt.Println("Ingrese el valor del radio:")
		var radio float64
		fmt.Scanf("%f", &radio)
		myCirculo := pki.Circulo{Radio: radio}
		pki.CalculaArea(myCirculo)
	} else if figura == "Triangulo" {
		fmt.Println("Ingrese el valor de la base:")
		var base float64
		fmt.Scanf("%f", &base)
		fmt.Println("Ingrese el valor de la altura:")
		var altura float64
		fmt.Scanf("%f", &altura)
		myTriangulo := pki.Triangulo{Base: base, Altura: altura}
		pki.CalculaArea(myTriangulo)
	} else {
		fmt.Println("Figura no valida porfavor vuelva a intentarlo")
		fmt.Println("**********************************************")
		main()
	}
}

// Package

package packageinterfaces

import (
	"fmt"
)

type Figuras2D interface {
	Area() float64
}

type Cudrado struct {
	Base float64
}

type Rectangulo struct {
	Base   float64
	Altura float64
}

type Circulo struct {
	Radio float64
}

type Triangulo struct {
	Base   float64
	Altura float64
}

func (c Cudrado) Area() float64 {
	return c.Base * c.Base
}

func (r Rectangulo) Area() float64 {
	return r.Base * r.Altura
}

func (c Circulo) Area() float64 {
	return 3.14 * c.Radio
}

func (t Triangulo) Area() float64 {
	return t.Base * t.Altura / 2
}

func CalculaArea(f Figuras2D) {
	fmt.Println("Area:", f.Area())
}



> 

Hola, desarroll茅 esta soluci贸n para ejecutar la funci贸n que tienen en comun un conjunto de instancias de los struct que implementen una interface

	// llamar la funcion calcular para cada elemento de
	// un slice del tipo figuras2D
	myInterfaceList := []figuras2D{myCuadrado, myRectangulo}
	for _, value := range myInterfaceList {
		calcular(value)
	}
package main

import "fmt"

type cuadrado struct {
	base float64
}

type figuras2d interface {
	area() float64
}

type rectangulo struct {
	base   float64
	altura float64
}

func (c cuadrado) area() float64 {
	return c.base * c.base
}

func calcular(f figuras2d) {
	fmt.Println("Area:", f.area())
}

func (r rectangulo) area() float64 {
	return r.base * r.altura
}

func main() {
	myCuadrado := cuadrado{base: 2}
	myRectangulo := rectangulo{base: 2, altura: 4}

	calcular(myCuadrado)
	calcular(myRectangulo)

	// Lista de interfaces
	myInterface := []interface{}{"Hola", 12, 4.90}
	fmt.Println(myInterface...)
}

triangle.go

package figures

import "fmt"

type Triangle struct {
	base float64
	hight float64
}

func NewTriangle(base, hight float64) Triangle {
	return Triangle{base, hight}
}

func (f Triangle) GetArea() float64 {
	return  f.base * f.hight / 2
}

func (f Triangle) String() string  {
	return fmt.Sprintf("{ base:%.1f, heght:%.1f, area:%.1f }", f.base, f.hight, f.GetArea())
} 

square.go

package figures

import "fmt"

type Square struct {
	base float64
}

func NewSquare(base float64) Square {
	return Square{base}
}

func (f Square) GetArea() float64 {
	return  f.base + f.base
}

func (f Square) String() string  {
	return fmt.Sprintf("{ base:%.1f, area:%.1f }", f.base, f.GetArea())
} 

circle.go

package figures

import (
	"fmt"
	"math"
)

type Circle struct {
	radio float64
}

func NewCircle(radio float64) Circle {
	return Circle{radio}
}

func (f Circle) GetArea() float64 {
	return  math.Pi * f.radio * f.radio
}

func (f Circle) String() string  {
	return fmt.Sprintf("{ radio:%.1f, area:%.1f }", f.radio, f.GetArea())
} 

rectangle.go

package figures

import "fmt"

type Rectangle struct {
	base float64
	hight float64
}

func NewRectangle(base, hight float64) Rectangle {
	return Rectangle{base, hight}
}

func (f Rectangle) GetArea() float64 {
	return  f.base + f.hight
}

func (f Rectangle) String() string  {
	return fmt.Sprintf("{ base:%.1f, heght:%.1f, area:%.1f }", f.base, f.hight, f.GetArea())
} 

CODIGO

package main

import (
	"fmt"
	"golang-base/practices/src/figures"
	"reflect"
)

type figuras2D interface {
	GetArea() float64
}

func  calcular(f figuras2D) float64 {
	return f.GetArea()
}

func main() {
	// Creacion de figuras
	myCircle := figures.NewCircle(10)
	myRectangle := figures.NewRectangle(40,20)
	mySquare := figures.NewSquare(30)
	myTrapeze := figures.NewTrapeze(60,40,10)
	myTriangle := figures.NewTriangle(40,30)

	// Lista de interfaces
	myInterface := []interface{}{myCircle, myRectangle, mySquare, myTrapeze, myTriangle}
	fmt.Println("=======  F I G U R A S  =======")
	for _, v := range myInterface {
		fmt.Printf("%s ==> %v \n", reflect.TypeOf(v), v)
	}

	// Calculo del area de las figuras
	fmt.Println("\n=======  A R E A S  =======")
	fmt.Printf("Rectangle-Area = %.2f \n", calcular(myRectangle))
	fmt.Printf("Circle-Area = %.2f \n", calcular(myCircle))
	fmt.Printf("Square-Area = %.2f \n", calcular(mySquare))
	fmt.Printf("Trapeze-Area = %.2f \n", calcular(myTrapeze))
	fmt.Printf("Triangle-Area = %.2f \n", calcular(myTriangle))
} 

EJECUCION

=======  F I G U R A S  =======
figures.Circle ==> { radio:10.0, area:314.2 } 
figures.Rectangle ==> { base:40.0, heght:20.0, area:60.0 } 
figures.Square ==> { base:30.0, area:60.0 } 
figures.Trapeze ==> { base:60.0, top:40.0, heght:10.0, area:500.0 } 
figures.Triangle ==> { base:40.0, heght:30.0, area:600.0 } 

=======  A R E A S  =======
Rectangle-Area = 60.00 
Circle-Area = 314.16 
Square-Area = 60.00 
Trapeze-Area = 500.00 
Triangle-Area = 600.00