Skip to content

Commit f94c6fc

Browse files
author
ma0
committed
1 parent fcbfc56 commit f94c6fc

File tree

8 files changed

+2280
-0
lines changed

8 files changed

+2280
-0
lines changed

es/02.2.md

+478
Large diffs are not rendered by default.

es/02.3.md

+516
Large diffs are not rendered by default.

es/02.4.md

+214
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# 2.4 struct
2+
3+
## struct
4+
5+
Podemos definir en Go nuevos tipos de contenedores con otras propiedades o campos como en otros lenguajes de programación. Por ejemplo, podemos crear el tipo llamado `persona` para representar una persona, este tipo tiene nombre y edad. Podemos llamar estos tipos de tipos como `struct`.
6+
```
7+
type persona struct {
8+
nombre string
9+
edad int
10+
}
11+
```
12+
Mira que fácil es definir un `struct`!
13+
14+
Tiene dos campos.
15+
16+
- `nombre` es una `string` usada para guardar el nombre de personas.
17+
- `edad` es un `int` usado para guardar la de edad de personas.
18+
19+
Vamos a ver como usarlo.
20+
```
21+
type persona struct {
22+
nombre string
23+
edad int
24+
}
25+
```
26+
var P persona // p es de tipo persona
27+
28+
P.nombre = "Astaxie" // asigna "Astaxie" al campo 'nombre' de p
29+
P.edad = 25 // asigna 25 al campo 'edad' de p
30+
fmt.Printf("El nombre de la persona es %s\n", P.name) // accedemos al campo 'nombre' de p
31+
32+
Tenemos tres formas mas de definir un struct.
33+
34+
- Asignando un valor inicial en forma ordenada
35+
36+
P := persona{"Tom", 25}
37+
38+
- Usando el formato `campo:valor` para inicializarlo sin orden
39+
40+
P := persona{edad:24, nombre:"Bob"}
41+
42+
- Definimos una struct anónima, y la inicializamos
43+
44+
P := struct{nombre string; edad int}{"Amy",18}
45+
46+
Vamos a ver un ejemplo completo.
47+
```
48+
package main
49+
import "fmt"
50+
51+
// definimos un tipo nuevo
52+
type persona struct {
53+
nombre string
54+
edad int
55+
}
56+
57+
// comparamos la edad de dos personas, y devolvemos la mas vieja con la
58+
// diferencia, struct es pasado por valor
59+
func Older(p1, p2 persona) (persona, int) {
60+
if p1.edad>p2.edad {
61+
return p1, p1.edad-p2.edad
62+
}
63+
return p2, p2.edad-p1.edad
64+
}
65+
66+
func main() {
67+
var tom persona
68+
69+
// inicialización
70+
tom.nombre, tom.edad = "Tom", 18
71+
72+
// inicializamos los dos valores con el formato "campo:valor"
73+
bob := persona{edad:25, nombre:"Bob"}
74+
75+
// inicializamos los dos valores en orden
76+
paul := persona{"Paul", 43}
77+
78+
tb_Older, tb_diff := Older(tom, bob)
79+
tp_Older, tp_diff := Older(tom, paul)
80+
bp_Older, bp_diff := Older(bob, paul)
81+
82+
fmt.Printf("De %s y %s, %s es mas viejo por %d años\n", tom.nombre, bob.nombre , tb_Older.nombre , tb_diff)
83+
84+
fmt.Printf("De %s y %s, %s es mas viejo por %d años\n", tom.nombre, paul.nombre, tp_Older.nombre, tp_diff)
85+
86+
fmt.Printf("De %s y %s, %s es mas viejo por %d años\n", bob.nombre, paul.nombre, bp_Older.nombre, bp_diff)
87+
}
88+
```
89+
### Campos incrustados en un struct
90+
91+
Solo les mostré como definir struct con campos que tienen nombre y tipo. De hecho, Go soporta campos sin nombre pero si con tipo, vamos a llamar a estos campos incrustados.
92+
93+
Cuando el campo incrustado es un struct, todos los campos de ese struct serán campos del nuevo struct de forma implícita.
94+
95+
Vamos a ver un ejemplo.
96+
```
97+
package main
98+
import "fmt"
99+
100+
type Human struct {
101+
name string
102+
age int
103+
weight int
104+
}
105+
106+
type Student struct {
107+
Human // campo incrustado, esto significa que el struct Student va a incluir los campos que tiene Human.
108+
speciality string
109+
}
110+
111+
func main() {
112+
// inicializamos a student
113+
mark := Student{Human{"Mark", 25, 120}, "Computer Science"}
114+
115+
// campos accesibles
116+
fmt.Println("Su nombre es ", mark.name)
117+
fmt.Println("Su edad es ", mark.age)
118+
fmt.Println("Su peso es ", mark.weight)
119+
fmt.Println("Su especialidad es ", mark.speciality)
120+
// modificamos un campo
121+
mark.speciality = "AI"
122+
fmt.Println("Mark cambio su especialidad")
123+
fmt.Println("Su especialidad es ", mark.speciality)
124+
// modificamos su edad
125+
fmt.Println("Mark esta mas viejo")
126+
mark.age = 46
127+
fmt.Println("Su edad es ", mark.age)
128+
// modificamos su peso
129+
fmt.Println("Mark ya no es mas un atleta")
130+
mark.weight += 60
131+
fmt.Println("Su peso es ", mark.weight)
132+
}
133+
```
134+
![](images/2.4.student_struct.png?raw=true)
135+
136+
Figure 2.7 Herencia en Student y Human
137+
138+
Vemos que accedemos a la edad y nombre en Student de la misma forma que lo hacemos con Human. Así es como funcionan los campos incrustados. Es muy útil “cool”, no lo es? Espera, hay algo todavía mas “cool”! Puede utilizar a Student para acceder a los campos incrustados de Human!
139+
140+
mark.Human = Human{"Marcus", 55, 220}
141+
mark.Human.age -= 1
142+
143+
Todos los tipos pueden ser utilizados como campos incrustados.
144+
```
145+
package main
146+
import "fmt"
147+
148+
type Skills []string
149+
150+
type Human struct {
151+
name string
152+
age int
153+
weight int
154+
}
155+
156+
type Student struct {
157+
Human // struct como un campo incrustado
158+
Skills // string como un campo incrustado
159+
int // usamos un tipo embebido como un campo incrustado
160+
speciality string
161+
}
162+
163+
func main() {
164+
// inicializamos al Student Jane
165+
jane := Student{Human:Human{"Jane", 35, 100}, speciality:"Biology"}
166+
// accedemos a sus campos
167+
fmt.Println("Su nombre es ", jane.name)
168+
fmt.Println("Su edad es , jane.age)
169+
fmt.Println("Su peso es ", jane.weight)
170+
fmt.Println("Su especialidad es ", jane.speciality)
171+
// modificamos el valor del campo skill
172+
jane.Skills = []string{"anatomy"}
173+
fmt.Println("Sus habilidades son ", jane.Skills)
174+
fmt.Println("Ella adquirió don habilidades mas ")
175+
jane.Skills = append(jane.Skills, "physics", "golang")
176+
fmt.Println("Sus habilidades ahora son ", jane.Skills)
177+
// modificamos un campo embebido
178+
jane.int = 3
179+
fmt.Println("Su numero preferido es ", jane.int)
180+
}
181+
```
182+
En el ejemplo anterior, podemos ver que a todos los tipos se les pueden incrustar campos y podemos utilizar funciones para operarlos.
183+
184+
Hay un problema mas, si Human tiene un campo llamado `phone` y Student tiene otro campo llamado con el mismo nombre, que deberíamos hacer?
185+
186+
Go utiliza una forma muy sencilla para resolverlo. Los campos exteriores consiguen accesos superiores, lo que significa, es que cuando se accede a `student.phone`, obtendremos el campo llamado phone en student, no en el struct de Human. Esta característica se puede ver simplemente como una `sobrecarga` de campos.
187+
```
188+
package main
189+
import "fmt"
190+
191+
type Human struct {
192+
name string
193+
age int
194+
phone string // Human tiene el campo phone
195+
}
196+
197+
type Employee struct {
198+
Human // campo embebido Human
199+
speciality string
200+
phone string // phone en employee
201+
}
202+
203+
func main() {
204+
Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"}
205+
fmt.Println("El teléfono del trabajo de Bob es:", Bob.phone)
206+
// accedemos al campo phone en Human
207+
fmt.Println("El teléfono personal de Bob es:", Bob.Human.phone)
208+
}
209+
```
210+
## Enlaces
211+
212+
- [Indice](preface.md)
213+
- Sección anterior: [Sentencias de control y funciones](02.3.md)
214+
- Siguiente sección: [Orientado a objetos](02.5.md)

0 commit comments

Comments
 (0)