479 lines
20 KiB
Markdown
479 lines
20 KiB
Markdown
# 2.2 Principios de Go
|
||
|
||
En esta sección, vamos a aprender como definir constantes, variables con tipos básicos y algunos conocimientos mas de la programación en Go.
|
||
|
||
## Definición de variables
|
||
|
||
Tenemos muchas formas diferentes de definir variables con la sintaxis de Go.
|
||
|
||
Utilizando la palabra reservada `var` es la forma básica de definir una variable, observe como en Go se coloca el tipo de variable luego del nombre de la misma.
|
||
```
|
||
// definición de una variables de nombre “variableName” y tipo "type"
|
||
var variableName type
|
||
```
|
||
Definición de múltiples variables.
|
||
```
|
||
// definimos tres variables donde su tipo es "type"
|
||
var vname1, vname2, vname3 type
|
||
```
|
||
Definición de una variable con un valor inicial.
|
||
```
|
||
// definición de una variable de nombre “variableName”, tipo "type" y valor "value"
|
||
var variableName type = value
|
||
```
|
||
Definición de múltiples variables con valores iniciales.
|
||
```
|
||
/*
|
||
Definición de tres variables de tipo "type", y sus valores iniciales.
|
||
vname1 de valor v1, vname2 de valor v2, vname3 de valor v3
|
||
*/
|
||
var vname1, vname2, vname3 type = v1, v2, v3
|
||
```
|
||
¿Crees que es muy tedioso utilizar las anteriores formas para definir variables? Entonces no te preocupes, porque el equipo de desarrollo de Go también se encontró con este problema.
|
||
Por lo que si deseas definir una variable con valores iniciales, podemos omitir el tipo de cada una,
|
||
por lo que el código quedaría algo así:
|
||
```
|
||
/*
|
||
Definición de tres variables de tipo "type", y sus valores iniciales.
|
||
vname1 de valor v1,vname2 de valor v2,vname3 de valor v3
|
||
*/
|
||
var vname1, vname2, vname3 = v1, v2, v3
|
||
```
|
||
Bueno, se que aun no es lo suficientemente sencillo. Vamos a ver como lo mejoramos.
|
||
```
|
||
/*
|
||
Definición de tres variables de tipo "type", y sus valores iniciales.
|
||
vname1 de valor v1,vname2 de valor v2,vname3 de valor v3
|
||
*/
|
||
vname1, vname2, vname3 := v1, v2, v3
|
||
```
|
||
Ahora se ve mucho mejor. Usa `:=` para reemplazar a `var` y `type`, esto se llama declaración breve. Pero espera, esto tiene una limitante, esta forma de declaración solo puede ser utilizada dentro de una función. Si intentas utilizarla fuera del cuerpo de una función vas a recibir un error de compilación. Por lo que normalmente utilizamos `var` para definir variables globales, y podemos utilizar la declaración breve en `var()`.
|
||
|
||
`_` (guión bajo) es un nombre especial de variable, cualquier valor que le sea otorgado será ignorado. Por ejemplo, le otorgamos `35` a `b`, y descartamos el `34`.( ***Este ejemplo nos muestra como esto funciona. Parece inútil aquí porque normalmente lo utilizamos cuando tomamos los valores de retorno de una función.*** )
|
||
```
|
||
_, b := 34, 35
|
||
```
|
||
Si no utilizas alguna de las variables declaradas en el programa, el compilador les lanzara un error. Intenta compilar el siguiente código, ve que sucede.
|
||
```
|
||
package main
|
||
|
||
func main() {
|
||
var i int
|
||
}
|
||
```
|
||
## Constantes
|
||
|
||
Las llamadas constantes son los valores que se determinan en el momento de compilación, y que no se pueden modificar durante la ejecución. En Go, podemos utilizar números, booleanos o cadenas como tipos de constantes.
|
||
|
||
Definimos una constante de la siguiente manera.
|
||
```
|
||
const nombreConstante = valor
|
||
// podemos asignar el tipo de una constante si es necesario
|
||
const Pi float32 = 3.1415926
|
||
```
|
||
Otros ejemplos.
|
||
```
|
||
const Pi = 3.1415926
|
||
const i = 10000
|
||
const MaxThread = 10
|
||
const prefix = "astaxie_"
|
||
```
|
||
## Tipos básicos
|
||
|
||
### Booleanos
|
||
|
||
En Go, podemos usar `bool` para definir variables de tipo booleanas, su valor puede ser unicamente `true` o `false`, y `false` sera el valor por defecto. ( ***No puede convertir el tipos variables entre números y booleanos!*** )
|
||
```
|
||
// ejemplo de código
|
||
var isActive bool // variable global
|
||
var enabled, disabled = true, false // omitimos el tipo de las variables
|
||
func test() {
|
||
var available bool // variable local
|
||
valid := false // definición breve de una variable
|
||
available = true // asignación de un valor a una variable
|
||
}
|
||
```
|
||
### Tipos Numéricos
|
||
|
||
Tipos enteros incluyendo los enteros con signo y sin signo. Para esto Go tiene `int` y `uint` al mismo tiempo, ellos tienen la misma longitud, pero la longitud específica va a depender de su sistema operativo. Ellos utilizan 32-bits en sistemas operativos de 32-bits, y 64-bits en sistemas operativos de 64-bits. Go también tiene tipos que tienen una longitud específica incluyendo `rune`, `int8`, `int16`, `int32`, `int64`, `byte`, `uint8`, `uint16`, `uint32`, `uint64`. Tenga en cuenta que `rune` es el alias de `int32` y `byte` es el alias para `uint8`.
|
||
|
||
Algo importante que debes saber es que no puede asignar valores entre estos tipos, esta operación va a causar un error de compilación.
|
||
```
|
||
var a int8
|
||
|
||
var b int32
|
||
|
||
c := a + b
|
||
```
|
||
Aunque int32 tiene una longitud mayor que uint8, y tiene la misma longitud que int, pero no podrá asignar valores entre ellos. ( ***aquí c afirmará ser de tipo `int`*** )
|
||
|
||
Los tipos Float tienen `float32` y `float64`, y no tienen un tipo llamado `float`, este último solo es el tipo por defecto cuando se utiliza la declaración breve.
|
||
|
||
¿Eso es todo? ¡No! Go también tiene número complejos. `complex128` (con una parte de 64-bits reales y otra parte de 64-bits imaginarios) es el tipo por defecto, si necesitas un tipo mas pequeño, hay uno llamado `complex64` (con una parte de 32-bits reales y otra de 32-bits imaginarios). Su forma es `RE+IMi`, donde `RE` es la parte real e `IM` es la parte imaginaria, el último `i` es el número imaginario. Este es un ejemplo de número complejo.
|
||
```
|
||
var c complex64 = 5+5i
|
||
//salida: (5+5i)
|
||
fmt.Printf("Value is: %v", c)
|
||
```
|
||
### Cadenas
|
||
|
||
Acabamos de hablar sobre que Go utiliza el juego de caracteres de UTF-8. Las Strings son representadas mediante comillas dobles `""` o comillas simples ``` `` ```.
|
||
```
|
||
// ejemplo de código
|
||
var frenchHello string // forma básica de definir una cadena
|
||
var emptyString string = "" // definimos una cadena con un valor vacío
|
||
func test() {
|
||
no, yes, maybe := "no", "yes", "maybe" // declaración breve
|
||
japaneseHello := "Ohaiou"
|
||
frenchHello = "Bonjour" // forma básica para asignar un valor
|
||
}
|
||
```
|
||
Es imposible cambiar el valor de una cadena por su índice. Vas a obtener un error cuando compiles el siguiente código.
|
||
```
|
||
var s string = "hello"
|
||
s[0] = 'c'
|
||
```
|
||
Pero, y si ¿realmente deseo cambiar el valor de un solo carácter de una string? Intenta utilizar el siguiente código.
|
||
```
|
||
s := "hello"
|
||
c := []byte(s) // convertimos una string a un tipo []byte
|
||
c[0] = 'c'
|
||
s2 := string(c) // volvemos a convertirlo a un tipo string
|
||
fmt.Printf("%s\n", s2)
|
||
```
|
||
Podemos utilizar el operador `+` para combinar dos cadenas.
|
||
```
|
||
s := "hello,"
|
||
m := " world"
|
||
a := s + m
|
||
fmt.Printf("%s\n", a)
|
||
```
|
||
y también.
|
||
```
|
||
s := "hello"
|
||
s = "c" + s[1:] // no puede cambiar los valores de una cadena por su índices pero puedes obtener sus valores.
|
||
fmt.Printf("%s\n", s)
|
||
```
|
||
Que pasa si ¿quiero tener una string de varias líneas?
|
||
```
|
||
m := `hello
|
||
world`
|
||
```
|
||
` `` ` capturará todos los caracteres en una cadena.
|
||
|
||
### Tipos de Errores
|
||
|
||
Go tiene un tipo de `error` para hacer frente a los mensajes de error. También tiene un paquete llamado `errors` para manejar los errores.
|
||
```
|
||
err := errors.New("emit macho dwarf: elf header corrupted")
|
||
if err != nil {
|
||
fmt.Print(err)
|
||
}
|
||
```
|
||
### Estructura de datos fundamental
|
||
|
||
La siguiente imagen viene de un artículo sobre [Estructuras de datos en Go](http://research.swtch.com/godata) en [El Blog de Russ Cox](http://research.swtch.com/). Como puedes ver, Go nos da bloques de memoria para almacenar datos.
|
||
|
||

|
||
|
||
Imagen 2.1 Go estructura de datos fundamental
|
||
|
||
## Algunas facilidades
|
||
|
||
### Definir por grupo
|
||
|
||
Si deseas definir múltiples constantes, variables o importaciones de paquetes, podemos utilizar formularios de grupos.
|
||
|
||
Forma básica.
|
||
```
|
||
import "fmt"
|
||
import "os"
|
||
|
||
const i = 100
|
||
const pi = 3.1415
|
||
const prefix = "Go_"
|
||
|
||
var i int
|
||
var pi float32
|
||
var prefix string
|
||
```
|
||
Forma de grupo.
|
||
```
|
||
import(
|
||
"fmt"
|
||
"os"
|
||
)
|
||
|
||
const(
|
||
i = 100
|
||
pi = 3.1415
|
||
prefix = "Go_"
|
||
)
|
||
|
||
var(
|
||
i int
|
||
pi float32
|
||
prefix string
|
||
)
|
||
```
|
||
A menos que asignes el valor de la constante `iota`, el primer valor de la constante en el grupo `const()` va a ser `0`. Si a las siguientes constantes no se les asignan valores explícitamente, sus valores serán el mismo que el último. Si el último valor de la constante es `iota`, los valores de las siguientes constantes que no son asignadas también serán `iota`.
|
||
|
||
### Enumerar con iota
|
||
|
||
Go tiene la palabra reservada `iota`, esta palabra reservada va a crear un `enum`, que va a comenzar con `0`, y se va a ir incrementando en `1`.
|
||
```
|
||
const(
|
||
x = iota // x == 0
|
||
y = iota // y == 1
|
||
z = iota // z == 2
|
||
w // Si no hay una expresión después del nombre de la contasnte, se usa la última expresión,
|
||
//entonces aquí nos dice que w = iota implícitamente. Por lo tanto w == 3, e y y x los dos, podrían omitir "= iota" de la misma forma.
|
||
)
|
||
|
||
const v = iota // cuando se vuelve a utilizar la palabra reservada `const` seguida de la asignación iota nuevamente, este reinicia su valor a `0`, por esto v = 0.
|
||
|
||
const (
|
||
e, f, g = iota, iota, iota // e=0,f=0,g=0 mismos valores de iota en una línea.
|
||
)
|
||
```
|
||
### Algunas reglas
|
||
|
||
La razón por la que Go es conciso es porque tiene algunos comportamientos por defecto.
|
||
|
||
- Cualquier variables que comience con mayúscula se va exportar como pública, de otra manera será una variable privada.
|
||
- Se usa la misma regla para funciones y constantes, no existen las palabras reservadas `public` o `private` en Go.
|
||
|
||
## Arreglos, segmentos, mapas
|
||
|
||
### Arreglos (array)
|
||
|
||
`array` es un arreglo obviamente, lo definimos de la siguiente forma.
|
||
```
|
||
var arr [n]type
|
||
```
|
||
en `[n]type`, `n` es la longitud del arreglo, `type` es el tipo de elementos que contiene. Como en otros lenguajes, utilizamos `[]` para obtener o establecer los elementos en el array.
|
||
```
|
||
var arr [10]int // un arraglo de tipo int
|
||
arr[0] = 42 // los arreglos arrancan su índice en 0
|
||
arr[1] = 13 // asignamos un valor a un elemento
|
||
fmt.Printf("El primer elemento es %d\n", arr[0])
|
||
// obtenemos el valor del elemento, este nos devolvera 42
|
||
fmt.Printf("El último elemento es %d\n", arr[9])
|
||
//este nos devolverá el valor por defecto del elemento número 10 en este array, que es 0 en este caso.
|
||
```
|
||
Debido a que la longitud es una parte del tipo del arreglo, `[3]int` y `[4]int` son diferentes tipos, por lo que no podemos cambiar la longitud del arreglos. Cuando utilizamos arreglos como argumentos, las funciones reciben copias en lugar de referencias a ellos! Si lo que busca es utilizar referencias, es posible que desee utilizar `slice` de las que vamos a hablar más adelante.
|
||
|
||
Es posible usar `:=` cuando definimos arrays.
|
||
```
|
||
a := [3]int{1, 2, 3} // define un arreglo de int con 3 elementos
|
||
|
||
b := [10]int{1, 2, 3}
|
||
// define arreglo de int con 10 elementos, y los tres primeros son asignados
|
||
// el resto utiliza el valor por defecto 0.
|
||
|
||
c := [...]int{4, 5, 6} // usamos `…` para reemplazar el número de la longitud, Go la va a calcular por ti.
|
||
```
|
||
Es posible que desee utilizar arreglos como elementos de un arreglo, vamos a ver como hacerlo.
|
||
```
|
||
// definimos un arreglo de dos dimensiones con dos elementos, y cada elemento tiene cuatro elementos.
|
||
arregloDoble := [2][4]int{[4]int{1, 2, 3, 4}, [4]int{5, 6, 7, 8}}
|
||
|
||
// podemos escribirlo de una forma más corta.
|
||
arregloSimple := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}}
|
||
```
|
||
Arreglo: estructuras de datos fundamentales.
|
||
|
||

|
||
|
||
Imagen 2.2 Relación de mapeo de arreglo multi-dimensional
|
||
|
||
### Segmentos (slice)
|
||
|
||
En muchas situaciones, un arreglo no es una buena elección. Por ejemplo, nosotros no sabemos cual va a ser el largo del arreglo cuando lo definimos, entonces vamos a necesitar un "arreglo dinámico". Este es llamado `slice` en Go.
|
||
|
||
Un `segmento` no es realmente un `arreglo dinámico`, es un tipo referenciado. Un `segmento` apunta a un `arreglo` subyacente, su declaración es similar a los `arreglos`, pero no necesitan una longitud.
|
||
```
|
||
// al igual que como definimos un arreglo, pero no le pasamos la longitud esta vez
|
||
var fsegmento []int
|
||
```
|
||
Entonces definimos un `segmento`, e inicializamos sus datos.
|
||
```
|
||
segmento := []byte {'a', 'b', 'c', 'd'}
|
||
```
|
||
Un `segmento` puede ser re-definido desde otro slice o array existente. Un `segmento` usa `arreglo[i:j]` para tomar sus valores, donde `i` es
|
||
el índice del comienzo y `j` es el índice del final, note que `arreglo[j]` no será segmentado, porque la longitud
|
||
del segmento es `j-i`.
|
||
```
|
||
// definimos un segmento con 10 elementos donde el tipo es byte
|
||
var ar = [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
|
||
|
||
// definimos dos segmento de tipo []byte
|
||
var a, b []byte
|
||
|
||
// a apunta a los elementos del tercero al quinto elemento en el array ar.
|
||
a = ar[2:5]
|
||
// ahora tiene los elementos ar[2],ar[3] y ar[4]
|
||
|
||
// b es otro slice del array ar
|
||
b = ar[3:5]
|
||
// ahora b tiene los elementos ar[3] y ar[4]
|
||
```
|
||
Note la diferencia entre `segmento` y `arreglo` cuando los definimos. Nosotros usamos `[…]` para que Go
|
||
calcule la longitud pero usamos`[]` para definir unicamente un segmento.
|
||
|
||
La estructura de datos subyacente a un segmento.
|
||
|
||

|
||
|
||
Imagen 2.3 Similitud entre slice y array
|
||
|
||
Los segmentos tienen algunas operaciones utiles.
|
||
|
||
- Un `segmento` comienza en 0, `ar[:n]` es igual a `ar[0:n]`
|
||
- El segundo índice sera la longitud del `slice` si lo omitimos, `ar[n:]` será igual a `ar[n:len(ar)]`.
|
||
- Se puede usar `ar[:]` para tomar todo el arreglo, la razón de esto se explica en las dos anteriores explicaciones.
|
||
|
||
Más ejemplos acerca de `segmentos`
|
||
```
|
||
// definimos un arreglo
|
||
var array = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
|
||
// definimos dos segmentos
|
||
var aSlice, bSlice []byte
|
||
|
||
// Algunas operaciones útiles
|
||
aSlice = array[:3] // es igual a aSlice = array[0:3] aSlice tiene los elementos a,b,c
|
||
aSlice = array[5:] // es igual a aSlice = array[5:10] aSlice tiene los elementos f,g,h,i,j
|
||
aSlice = array[:] // es igual a aSlice = array[0:10] aSlice tiene todos los elementos
|
||
|
||
// segmento desde segmento
|
||
aSlice = array[3:7] // aSlice tiene los elementos d,e,f,g,len=4,cap=7
|
||
bSlice = aSlice[1:3] // bSlice contiene aSlice[1], aSlice[2], entonces este tendrá los elementos e,f
|
||
bSlice = aSlice[:3] // bSlice contiene aSlice[0], aSlice[1], aSlice[2], entonces este tiene d,e,f
|
||
bSlice = aSlice[0:5] // bSlice se puede expandir, ahora bSlice contiene d,e,f,g,h
|
||
bSlice = aSlice[:] // bSlice tiene los mismos elementos que aSlice, que son d,e,f,g
|
||
```
|
||
Un `segmento` es un tipo de referencia, por lo que si uno se modifica entonces afectará al resto.
|
||
Por ejemplo, con los elementos de anteriores `aSlice` y `bSlice`, si se modifica el valor de algún elemento en `aSlice`,
|
||
`bSlice` será modificado también.
|
||
|
||
`slice` por definición es como una estructura, y contiene tres partes.
|
||
|
||
- Un puntero que apunta donde comienza el `segmento`.
|
||
- la longitud del `segmento`.
|
||
- Capacidad, la longitud de donde comienza el indice hacia donde termina el indice del `slice`.
|
||
```
|
||
Array_a := [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
|
||
Slice_a := Array_a[2:5]
|
||
```
|
||
Los fundamentos de la estructura de datos del código anterior es el siguiente.
|
||
|
||

|
||
|
||
Imagen 2.4 Array información del slice
|
||
|
||
Hay algunas funciones integradas para los segmentos.
|
||
|
||
- `len` nos devuelve la longitud del `segmento`.
|
||
- `cap` nos devuelve la longitud máxima del `segmento`
|
||
- `append` añade uno o mas elementos al `segmento`, y nos devuelve el `segmento` .
|
||
- `copy` copia elementos de un segmento hacia otro, y nos devuelve el número de elementos que fueron copiados.
|
||
|
||
Atención: `append` va a cambiar el array al que apunta el `slice`, y afectará a los otros que apuntan al mismo array.
|
||
Ademas si no tiene una longitud suficiente para el slice (`(cap-len) == 0`), `append` nos va a devolver un nuevo array para este slice, en este punto,
|
||
los otros slices van a apuntan al anterior array nos serán afectados.
|
||
|
||
### Mapas (map)
|
||
|
||
Un `mapa` es como un diccionario en Python, lo usamos de la siguiente forma `mapa[claveTipo]tipoValor` para definirlo.
|
||
|
||
Vamos a ver algo de código, para configurar o tomar un valor de un `mapa` es como en un `segmento`, usamos la `llave` para ello, pero el indice en un `segmento` puede ser
|
||
solo de tipo entero, y en un `mapa` podemos usar mucho mas que eso, `entero`, `cadena`, o lo que quieras. Ademas, todos ellos
|
||
pueden utilizar `==` y `!=` para comparar valores.
|
||
```
|
||
// usamos string tipo de llave (key), int como el tipo de valor, y debemos usar `make` para inicializarlo.
|
||
var numbers map[string] int
|
||
// otra forma de definir un mapa
|
||
numbers := make(map[string]int)
|
||
numbers["one"] = 1 // asignamos el valor para la clave
|
||
numbers["ten"] = 10
|
||
numbers["three"] = 3
|
||
|
||
fmt.Println("El tercer número es: ", numbers["three"]) // tomamos el valor
|
||
// Esto imprime: El tercer número es: 3
|
||
```
|
||
Algunas cosas a tener en cuenta cuando usamos map.
|
||
|
||
- Un `mapa` está y es desordenado, cada vez que imprimamos un `mapa` vamos a obtener diferentes resultados. Es imposible obtener un valor por índice, debe usar la clave.
|
||
- Un `mapa` no tiene una longitud fija, es un tipo de referencia al igual que los `segmentos`.
|
||
- `len` también funciona con `mapas`, este devuelve el número de claves que tiene el map.
|
||
- Es muy sencillo modificar el valor de un elemento del `mapa`, simplemente usamos `numbers["one"]=11` para cambiar el valor que contiene la clave one a `11`.
|
||
|
||
Se puede usar la forma `clave:valor` para inicializar los valores del map, y `map` tiene internamente los métodos para verificar si la clave existe.
|
||
|
||
Utilice `delete` para borrar un elemento del `mapa`.
|
||
```
|
||
// Inicialice un mapa
|
||
rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }
|
||
// map nos devuelve dos valores. El segundo valor ,ok es false, si la clave no
|
||
//existe true de otra forma.
|
||
csharpRating, ok := rating["C#"]
|
||
if ok {
|
||
fmt.Println("C# se encuentra en el map y su ranking es ", csharpRating)
|
||
} else {
|
||
fmt.Println("No tenemos un ranking asociado con C# en este map")
|
||
}
|
||
|
||
delete(rating, "C") // borramos el elemento con la clave "c"
|
||
```
|
||
Como se dijo anteriormente, `map` es un tipo por referencia, si dos `map`s apuntan a los mismos datos,
|
||
cualquier cambio van a afectar a ambos.
|
||
```
|
||
m := make(map[string]string)
|
||
m["Hello"] = "Bonjour"
|
||
m1 := m
|
||
m1["Hello"] = "Salut" // ahora el valor de m["hello"] es Salut
|
||
```
|
||
### make, new
|
||
|
||
`make` realiza la asignación de memoria para construir las estructuras como los `mapas`, `segmentos`, o `canales`, `new`
|
||
es para la reserva de memoria de cada tipo.
|
||
|
||
`new(T)` reservamos la memoria para el valor vacío del tipo `T`'s, devuelve la dirección de memoria, que es el valor del tipo `*T`. En los términos de Go,
|
||
este devuelve un puntero, que apunta al valor vacío del tipo `T`.
|
||
|
||
`new` devuelve punteros.
|
||
|
||
La función incorporada `make(T, args)` tiene un diferente efecto que `new(T)`, `make` puede ser usado para `segmentos`, `mapas`,
|
||
y `canales`, y nos devuelve un valor inicializado con valor inicial del tipo `T`. La razón para hacer esto es porque estos tres tipos
|
||
por debajo deben ser inicializados antes que los punteros a ellos. Por ejemplo, un `segmento` contiene punteros que por debajo apuntan a
|
||
un `arreglo`, longitud y capacidad. Antes de que esta información sea inicializada, un `segmento` es `nil`, entonces para un `segmento`, `mapa`y
|
||
`canal`, `make` inicializa los datos que tienen por debajo, y asigna algunos valores configurables.
|
||
|
||
`make` devuelve valores distinto de cero.
|
||
|
||
La siguiente imagen nos muestra como son diferentes `new` y `make`.
|
||
|
||

|
||
|
||
Imagen 2.5 Reserva de memoria de fondo de make y new
|
||
|
||
En cuando a valor cero, no significa valor vacío. Es el valor de las variables cuando no son asignados de forma manual, usualmente es 0, esta es la lista de algunos de estos valores.
|
||
```
|
||
int 0
|
||
int8 0
|
||
int32 0
|
||
int64 0
|
||
uint 0x0
|
||
rune 0 // el tipo actual de rune es int32
|
||
byte 0x0 // el tipo actual de byte es uint8
|
||
float32 0 // la longitud es 4 byte
|
||
float64 0 // la longitud es 8 byte
|
||
bool false
|
||
string ""
|
||
```
|
||
## Enlaces
|
||
|
||
- [Indice](preface.md)
|
||
- Sección anterior: ["Hello, Go"](02.1.md)
|
||
- Siguiente sección: [Sentencias de control y funciones](02.3.md)
|