Merge pull request #508 from holocronweaver/master

[go/en][go/es] Fix several problems with Go tutorials
This commit is contained in:
Nami-Doc 2014-01-31 00:16:41 -08:00
commit bbce7c6d37
2 changed files with 184 additions and 153 deletions

View File

@ -7,16 +7,20 @@ contributors:
- ["Sonia Keys", "https://github.com/soniakeys"] - ["Sonia Keys", "https://github.com/soniakeys"]
translators: translators:
- ["Adrian Espinosa", "http://www.adrianespinosa.com"] - ["Adrian Espinosa", "http://www.adrianespinosa.com"]
- ["Jesse Johnson, "https://github.com/holocronweaver"]
lang: es-es lang: es-es
--- ---
Go fue creado por la necesidad de hacer el trabajo rápidamente. No es la última Go fue creado por la necesidad de hacer el trabajo rápidamente. No es
tendencia en informática, pero es la forma nueva y más rápida de resolver problemas reales. la última tendencia en informática, pero es la forma nueva y más
rápida de resolver problemas reales.
Tiene conceptos familiares de lenguajes imperativos con tipado
estático. Es rápido compilando y rápido al ejecutar, añade una
concurrencia fácil de entender para las CPUs de varios núcleos de hoy
en día, y tiene características que ayudan con la programación a gran
escala.
Tiene conceptos familiares de lenguajes imperativos con tipado estático.
Es rápido compilando y rápido al ejecutar, añade una concurrencia fácil de entender para las CPUs de varios núcleos de hoy en día, y tiene características que ayudan con la programación a gran escala.
Go viene con una librería estándar muy buena y una comunidad entusiasta. Go viene con una librería estándar muy buena y una comunidad entusiasta.
```go ```go
@ -28,15 +32,17 @@ Go viene con una librería estándar muy buena y una comunidad entusiasta.
// Main es un nombre especial que declara un ejecutable en vez de una librería. // Main es un nombre especial que declara un ejecutable en vez de una librería.
package main package main
// La declaración Import declara los paquetes de librerías referenciados en este archivo. // La declaración Import declara los paquetes de librerías
// referenciados en este archivo.
import ( import (
"fmt" // Un paquete en la librería estándar de Go "fmt" // Un paquete en la librería estándar de Go.
"net/http" // Sí, un servidor web! "net/http" // Sí, un servidor web!
"strconv" // Conversiones de cadenas "strconv" // Conversiones de cadenas.
m "math" // Librería matemáticas con alias local m.
) )
// Definición de una función. Main es especial. Es el punto de entrada para el ejecutable. // Definición de una función. Main es especial. Es el punto de
// Te guste o no, Go utiliza llaves. // entrada para el ejecutable. Te guste o no, Go utiliza llaves.
func main() { func main() {
// Println imprime una línea a stdout. // Println imprime una línea a stdout.
// Cualificalo con el nombre del paquete, fmt. // Cualificalo con el nombre del paquete, fmt.
@ -49,19 +55,19 @@ func main() {
// Las funciones llevan parámetros entre paréntesis. // Las funciones llevan parámetros entre paréntesis.
// Si no hay parámetros, los paréntesis siguen siendo obligatorios. // Si no hay parámetros, los paréntesis siguen siendo obligatorios.
func beyondHello() { func beyondHello() {
var x int // Declaración de una variable. Las variables se deben declarar antes de var x int // Declaración de una variable.
// utilizarlas. // Las variables se deben declarar antes de utilizarlas.
x = 3 // Asignación de variables. x = 3 // Asignación de variables.
// Declaración "corta" con := para inferir el tipo, declarar y asignar. // Declaración "corta" con := para inferir el tipo, declarar y asignar.
y := 4 y := 4
sum, prod := learnMultiple(x, y) // función devuelve dos valores sum, prod := learnMultiple(x, y) // Función devuelve dos valores.
fmt.Println("sum:", sum, "prod:", prod) // simple salida fmt.Println("sum:", sum, "prod:", prod) // Simple salida.
learnTypes() // < y minutes, learn more! learnTypes() // < y minutes, learn more!
} }
// Las funciones pueden tener parámetros y (múltiples!) valores de retorno. // Las funciones pueden tener parámetros y (múltiples!) valores de retorno.
func learnMultiple(x, y int) (sum, prod int) { func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // devolver dos valores return x + y, x * y // Devolver dos valores.
} }
// Algunos tipos incorporados y literales. // Algunos tipos incorporados y literales.
@ -73,32 +79,33 @@ func learnTypes() {
saltos de línea.` // mismo tipo cadena saltos de línea.` // mismo tipo cadena
// Literal no ASCII. Los fuentes de Go son UTF-8. // Literal no ASCII. Los fuentes de Go son UTF-8.
g := 'Σ' // tipo rune, un alias de uint32, alberga un punto unicode. g := 'Σ' // Tipo rune, un alias de uint32, alberga un punto unicode.
f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit.
c := 3 + 4i // complex128, representado internamente por dos float64 c := 3 + 4i // complex128, representado internamente por dos float64.
// Sintaxis Var con inicializadores. // Sintaxis Var con inicializadores.
var u uint = 7 // sin signo, pero la implementación depende del tamaño como en int var u uint = 7 // Sin signo, pero la implementación depende del
// tamaño como en int.
var pi float32 = 22. / 7 var pi float32 = 22. / 7
// Sintáxis de conversión con una declaración corta. // Sintáxis de conversión con una declaración corta.
n := byte('\n') // byte es un alias de uint8 n := byte('\n') // byte es un alias de uint8.
// Los Arrays tienen un tamaño fijo a la hora de compilar. // Los Arrays tienen un tamaño fijo a la hora de compilar.
var a4 [4]int // un array de 4 ints, inicializados a 0 var a4 [4]int // Un array de 4 ints, inicializados a 0.
a3 := [...]int{3, 1, 5} // un array de 3 ints, inicializados como se indica a3 := [...]int{3, 1, 5} // Un array de 3 ints, inicializados como se indica.
// Los Slices tienen tamaño dinámico. Los arrays y slices tienen sus ventajas // Los Slices tienen tamaño dinámico. Los arrays y slices tienen sus ventajas
// y desventajas pero los casos de uso para los slices son más comunes. // y desventajas pero los casos de uso para los slices son más comunes.
s3 := []int{4, 5, 9} // Comparar con a3. No hay puntos suspensivos s3 := []int{4, 5, 9} // Comparar con a3. No hay puntos suspensivos.
s4 := make([]int, 4) // Asigna slices de 4 ints, inicializados a 0 s4 := make([]int, 4) // Asigna slices de 4 ints, inicializados a 0.
var d2 [][]float64 // solo declaración, sin asignación var d2 [][]float64 // Solo declaración, sin asignación.
bs := []byte("a slice") // sintaxis de conversión de tipo bs := []byte("a slice") // Sintaxis de conversión de tipo.
p, q := learnMemory() // declara p, q para ser un tipo puntero a int. p, q := learnMemory() // Declara p, q para ser un tipo puntero a int.
fmt.Println(*p, *q) // * sigue un puntero. Esto imprime dos ints. fmt.Println(*p, *q) // * sigue un puntero. Esto imprime dos ints.
// Los Maps son arrays asociativos dinámicos, como los hash o diccionarios // Los Maps son arrays asociativos dinámicos, como los hash o
// de otros lenguajes // diccionarios de otros lenguajes.
m := map[string]int{"three": 3, "four": 4} m := map[string]int{"three": 3, "four": 4}
m["one"] = 1 m["one"] = 1
@ -108,23 +115,24 @@ saltos de línea.` // mismo tipo cadena
// Esto cuenta como utilización de variables. // Esto cuenta como utilización de variables.
fmt.Println(s, c, a4, s3, d2, m) fmt.Println(s, c, a4, s3, d2, m)
learnFlowControl() // vuelta al flujo learnFlowControl() // Vuelta al flujo.
} }
// Go posee recolector de basura. Tiene puntero pero no aritmética de punteros. // Go posee recolector de basura. Tiene puntero pero no aritmética de
// Puedes cometer un errores con un puntero nil, pero no incrementando un puntero. // punteros. Puedes cometer un errores con un puntero nil, pero no
// incrementando un puntero.
func learnMemory() (p, q *int) { func learnMemory() (p, q *int) {
// q y p tienen un tipo puntero a int. // q y p tienen un tipo puntero a int.
p = new(int) // función incorporada que asigna memoria. p = new(int) // Función incorporada que asigna memoria.
// La asignación de int se inicializa a 0, p ya no es nil. // La asignación de int se inicializa a 0, p ya no es nil.
s := make([]int, 20) // asigna 20 ints a un solo bloque de memoria. s := make([]int, 20) // Asigna 20 ints a un solo bloque de memoria.
s[3] = 7 // asignar uno de ellos s[3] = 7 // Asignar uno de ellos.
r := -2 // declarar otra variable local r := -2 // Declarar otra variable local.
return &s[3], &r // & toma la dirección de un objeto. return &s[3], &r // & toma la dirección de un objeto.
} }
func expensiveComputation() int { func expensiveComputation() float64 {
return 1e6 return m.Exp(10)
} }
func learnFlowControl() { func learnFlowControl() {
@ -134,29 +142,31 @@ func learnFlowControl() {
} }
// El formato está estandarizado por el comando "go fmt." // El formato está estandarizado por el comando "go fmt."
if false { if false {
// pout // Pout.
} else { } else {
// gloat // Gloat.
} }
// Utiliza switch preferiblemente para if encadenados. // Utiliza switch preferiblemente para if encadenados.
x := 1 x := 42.0
switch x { switch x {
case 0: case 0:
case 1: case 1:
// los cases no se mezclan, no requieren de "break" case 42:
case 2: // Los cases no se mezclan, no requieren de "break".
// no llega case 43:
// No llega.
} }
// Como if, for no utiliza paréntesis tampoco. // Como if, for no utiliza paréntesis tampoco.
for x := 0; x < 3; x++ { // ++ es una sentencia // Variables declaradas en for y if son locales de su ámbito local.
for x := 0; x < 3; x++ { // ++ es una sentencia.
fmt.Println("iteration", x) fmt.Println("iteration", x)
} }
// x == 1 aqui. // x == 42 aqui.
// For es la única sentencia de bucle en Go, pero tiene formas alternativas. // For es la única sentencia de bucle en Go, pero tiene formas alternativas.
for { // bucle infinito for { // Bucle infinito.
break // solo bromeaba! break // Solo bromeaba!
continue // no llega continue // No llega.
} }
// Como en for, := en una sentencia if significa declarar y asignar primero, // Como en for, := en una sentencia if significa declarar y asignar primero,
// luego comprobar y > x. // luego comprobar y > x.
@ -165,11 +175,11 @@ func learnFlowControl() {
} }
// Los literales de funciones son "closures". // Los literales de funciones son "closures".
xBig := func() bool { xBig := func() bool {
return x > 100 // referencia a x declarada encima de la sentencia switch. return x > 100 // Referencia a x declarada encima de la sentencia switch.
} }
fmt.Println("xBig:", xBig()) // verdadero (la última vez asignamos 1e6 a x) fmt.Println("xBig:", xBig()) // verdadero (la última vez asignamos 1e6 a x).
x /= 1e5 // esto lo hace == 10 x /= m.Exp(9) // Esto lo hace x == e.
fmt.Println("xBig:", xBig()) // ahora es falso fmt.Println("xBig:", xBig()) // Ahora es falso.
// Cuando lo necesites, te encantará. // Cuando lo necesites, te encantará.
goto love goto love
@ -199,16 +209,29 @@ func learnInterfaces() {
// La sintaxis de llaves es un "literal struct". Evalúa a un struct // La sintaxis de llaves es un "literal struct". Evalúa a un struct
// inicializado. La sintaxis := declara e inicializa p a este struct. // inicializado. La sintaxis := declara e inicializa p a este struct.
p := pair{3, 4} p := pair{3, 4}
fmt.Println(p.String()) // llamar al método String de p, de tipo pair. fmt.Println(p.String()) // Llamar al método String de p, de tipo pair.
var i Stringer // declarar i como interfaz tipo Stringer. var i Stringer // Declarar i como interfaz tipo Stringer.
i = p // válido porque pair implementa Stringer i = p // Válido porque pair implementa Stringer.
// Llamar al metodo String de i, de tipo Stringer. Misma salida que arriba // Llamar al metodo String de i, de tipo Stringer. Misma salida que arriba.
fmt.Println(i.String()) fmt.Println(i.String())
// Las funciones en el paquete fmt llaman al método String para preguntar a un objeto // Las funciones en el paquete fmt llaman al método String para
// por una versión imprimible de si mismo // preguntar a un objeto por una versión imprimible de si mismo.
fmt.Println(p) // salida igual que arriba. Println llama al método String. fmt.Println(p) // Salida igual que arriba. Println llama al método String.
fmt.Println(i) // salida igual que arriba. fmt.Println(i) // Salida igual que arriba.
learnVariadicParams("great", "learning", "here!")
}
// Las funciones pueden tener número variable de argumentos.
func learnVariadicParams(myStrings ...interface{}) {
// Iterar cada valor de la variadic.
for _, param := range myStrings {
fmt.Println("param:", param)
}
// Pasar valor variadic como parámetro variadic.
fmt.Println("params:", fmt.Sprintln(myStrings...))
learnErrorHandling() learnErrorHandling()
} }
@ -223,7 +246,7 @@ func learnErrorHandling() {
} }
// Un valor de error comunica más información sobre el problema aparte de "ok". // Un valor de error comunica más información sobre el problema aparte de "ok".
if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta el valor if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta el valor
// imprime "strconv.ParseInt: parsing "non-int": invalid syntax" // Imprime "strconv.ParseInt: parsing "non-int": invalid syntax".
fmt.Println(err) fmt.Println(err)
} }
// Revisarmeos las interfaces más tarde. Mientras tanto, // Revisarmeos las interfaces más tarde. Mientras tanto,
@ -248,25 +271,28 @@ func learnConcurrency() {
go inc(-805, c) go inc(-805, c)
// Leer los tres resultados del channel e imprimirlos. // Leer los tres resultados del channel e imprimirlos.
// No se puede saber en que orden llegarán los resultados! // No se puede saber en que orden llegarán los resultados!
fmt.Println(<-c, <-c, <-c) // channel a la derecha, <- es el operador "recibir". fmt.Println(<-c, <-c, <-c) // Channel a la derecha, <- es el operador "recibir".
cs := make(chan string) // otro channel, este gestiona cadenas. cs := make(chan string) // Otro channel, este gestiona cadenas.
cc := make(chan chan string) // un channel de cadenas de channels. ccs := make(chan chan string) // Un channel de cadenas de channels.
go func() { c <- 84 }() // iniciar una nueva goroutine solo para enviar un valor. go func() { c <- 84 }() // Iniciar una nueva goroutine solo para
go func() { cs <- "wordy" }() // otra vez, para cs en esta ocasión // enviar un valor.
// Select tiene una sintáxis parecida a la sentencia switch pero cada caso involucra go func() { cs <- "wordy" }() // Otra vez, para cs en esta ocasión.
// una operacion de channels. Selecciona un caso de forma aleatoria de los casos // Select tiene una sintáxis parecida a la sentencia switch pero
// que están listos para comunicarse. // cada caso involucra una operacion de channels. Selecciona un caso
// de forma aleatoria de los casos que están listos para comunicarse.
select { select {
case i := <-c: // el valor recibido puede ser asignado a una variable case i := <-c: // El valor recibido puede ser asignado a una variable,
fmt.Printf("it's a %T", i) fmt.Printf("it's a %T", i)
case <-cs: // o el valor puede ser descartado case <-cs: // o el valor puede ser descartado.
fmt.Println("it's a string") fmt.Println("it's a string")
case <-cc: // channel vacío, no está listo para la comunicación. case <-ccs: // Channel vacío, no está listo para la comunicación.
fmt.Println("didn't happen.") fmt.Println("didn't happen.")
} }
// En este punto un valor fue devuelvto de c o cs. Uno de las dos // En este punto un valor fue devuelvto de c o cs. Uno de las dos
// goroutines que se iniciaron se ha completado, la otrá permancerá bloqueada. // goroutines que se iniciaron se ha completado, la otrá permancerá
// bloqueada.
learnWebProgramming() // Go lo hace. Tu también quieres hacerlo. learnWebProgramming() // Go lo hace. Tu también quieres hacerlo.
} }
@ -281,7 +307,7 @@ func learnWebProgramming() {
// Haz pair un http.Handler implementando su único método, ServeHTTP. // Haz pair un http.Handler implementando su único método, ServeHTTP.
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Servir datos con un método de http.ResponseWriter // Servir datos con un método de http.ResponseWriter.
w.Write([]byte("You learned Go in Y minutes!")) w.Write([]byte("You learned Go in Y minutes!"))
} }
``` ```
@ -291,11 +317,12 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
La raíz de todas las cosas de Go es la [web oficial de Go](http://golang.org/). La raíz de todas las cosas de Go es la [web oficial de Go](http://golang.org/).
Ahí puedes seguir el tutorial, jugar interactivamente y leer mucho. Ahí puedes seguir el tutorial, jugar interactivamente y leer mucho.
La propia definición del lenguaje también está altamente recomendada. Es fácil de leer La propia definición del lenguaje también está altamente
e increíblemente corta (como otras definiciones de lenguajes hoy en día) recomendada. Es fácil de leer e increíblemente corta (como otras
definiciones de lenguajes hoy en día)
En la lista de lectura de estudiantes de Go está el código fuente de la En la lista de lectura de estudiantes de Go está el código fuente de
librería estándar. Muy bien documentada, demuestra lo mejor de Go leíble, comprendible, la librería estándar. Muy bien documentada, demuestra lo mejor de Go
estilo Go y formas Go. Pincha en el nombre de una función en la documentación leíble, comprendible, estilo Go y formas Go. Pincha en el nombre de
y te aparecerá el código fuente! una función en la documentación y te aparecerá el código fuente!

View File

@ -6,6 +6,7 @@ filename: learngo.go
contributors: contributors:
- ["Sonia Keys", "https://github.com/soniakeys"] - ["Sonia Keys", "https://github.com/soniakeys"]
- ["Christopher Bess", "https://github.com/cbess"] - ["Christopher Bess", "https://github.com/cbess"]
- ["Jesse Johnson", "https://github.com/holocronweaver"]
--- ---
Go was created out of the need to get work done. It's not the latest trend Go was created out of the need to get work done. It's not the latest trend
@ -30,9 +31,10 @@ package main
// Import declaration declares library packages referenced in this file. // Import declaration declares library packages referenced in this file.
import ( import (
"fmt" // A package in the Go standard library "fmt" // A package in the Go standard library.
"net/http" // Yes, a web server! "net/http" // Yes, a web server!
"strconv" // String conversions "strconv" // String conversions.
m "math" // Math library with local alias m.
) )
// A function definition. Main is special. It is the entry point for the // A function definition. Main is special. It is the entry point for the
@ -53,49 +55,49 @@ func beyondHello() {
x = 3 // Variable assignment. x = 3 // Variable assignment.
// "Short" declarations use := to infer the type, declare, and assign. // "Short" declarations use := to infer the type, declare, and assign.
y := 4 y := 4
sum, prod := learnMultiple(x, y) // function returns two values sum, prod := learnMultiple(x, y) // Function returns two values.
fmt.Println("sum:", sum, "prod:", prod) // simple output fmt.Println("sum:", sum, "prod:", prod) // Simple output.
learnTypes() // < y minutes, learn more! learnTypes() // < y minutes, learn more!
} }
// Functions can have parameters and (multiple!) return values. // Functions can have parameters and (multiple!) return values.
func learnMultiple(x, y int) (sum, prod int) { func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // return two values return x + y, x * y // Return two values.
} }
// Some built-in types and literals. // Some built-in types and literals.
func learnTypes() { func learnTypes() {
// Short declaration usually gives you what you want. // Short declaration usually gives you what you want.
s := "Learn Go!" // string type s := "Learn Go!" // string type.
s2 := `A "raw" string literal s2 := `A "raw" string literal
can include line breaks.` // same string type can include line breaks.` // Same string type.
// non-ASCII literal. Go source is UTF-8. // Non-ASCII literal. Go source is UTF-8.
g := 'Σ' // rune type, an alias for uint32, holds a unicode code point g := 'Σ' // rune type, an alias for uint32, holds a unicode code point.
f := 3.14195 // float64, an IEEE-754 64-bit floating point number f := 3.14195 // float64, an IEEE-754 64-bit floating point number.
c := 3 + 4i // complex128, represented internally with two float64s c := 3 + 4i // complex128, represented internally with two float64's.
// Var syntax with an initializers. // Var syntax with an initializers.
var u uint = 7 // unsigned, but implementation dependent size as with int var u uint = 7 // Unsigned, but implementation dependent size as with int.
var pi float32 = 22. / 7 var pi float32 = 22. / 7
// Conversion syntax with a short declaration. // Conversion syntax with a short declaration.
n := byte('\n') // byte is an alias for uint8 n := byte('\n') // byte is an alias for uint8.
// Arrays have size fixed at compile time. // Arrays have size fixed at compile time.
var a4 [4]int // an array of 4 ints, initialized to all 0 var a4 [4]int // An array of 4 ints, initialized to all 0.
a3 := [...]int{3, 1, 5} // an array of 3 ints, initialized as shown a3 := [...]int{3, 1, 5} // An array of 3 ints, initialized as shown.
// Slices have dynamic size. Arrays and slices each have advantages // Slices have dynamic size. Arrays and slices each have advantages
// but use cases for slices are much more common. // but use cases for slices are much more common.
s3 := []int{4, 5, 9} // compare to a3. no ellipsis here s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here.
s4 := make([]int, 4) // allocates slice of 4 ints, initialized to all 0 s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0.
var d2 [][]float64 // declaration only, nothing allocated here var d2 [][]float64 // Declaration only, nothing allocated here.
bs := []byte("a slice") // type conversion syntax bs := []byte("a slice") // Type conversion syntax.
p, q := learnMemory() // declares p, q to be type pointer to int. p, q := learnMemory() // Declares p, q to be type pointer to int.
fmt.Println(*p, *q) // * follows a pointer. This prints two ints. fmt.Println(*p, *q) // * follows a pointer. This prints two ints.
// Maps are a dynamically growable associative array type, like the // Maps are a dynamically growable associative array type, like the
@ -109,23 +111,23 @@ can include line breaks.` // same string type
// Output of course counts as using a variable. // Output of course counts as using a variable.
fmt.Println(s, c, a4, s3, d2, m) fmt.Println(s, c, a4, s3, d2, m)
learnFlowControl() // back in the flow learnFlowControl() // Back in the flow.
} }
// Go is fully garbage collected. It has pointers but no pointer arithmetic. // Go is fully garbage collected. It has pointers but no pointer arithmetic.
// You can make a mistake with a nil pointer, but not by incrementing a pointer. // You can make a mistake with a nil pointer, but not by incrementing a pointer.
func learnMemory() (p, q *int) { func learnMemory() (p, q *int) {
// Named return values p and q have type pointer to int. // Named return values p and q have type pointer to int.
p = new(int) // built-in function new allocates memory. p = new(int) // Built-in function new allocates memory.
// The allocated int is initialized to 0, p is no longer nil. // The allocated int is initialized to 0, p is no longer nil.
s := make([]int, 20) // allocate 20 ints as a single block of memory s := make([]int, 20) // Allocate 20 ints as a single block of memory.
s[3] = 7 // assign one of them s[3] = 7 // Assign one of them.
r := -2 // declare another local variable r := -2 // Declare another local variable.
return &s[3], &r // & takes the address of an object. return &s[3], &r // & takes the address of an object.
} }
func expensiveComputation() int { func expensiveComputation() float64 {
return 1e6 return m.Exp(10)
} }
func learnFlowControl() { func learnFlowControl() {
@ -135,29 +137,31 @@ func learnFlowControl() {
} }
// Formatting is standardized by the command line command "go fmt." // Formatting is standardized by the command line command "go fmt."
if false { if false {
// pout // Pout.
} else { } else {
// gloat // Gloat.
} }
// Use switch in preference to chained if statements. // Use switch in preference to chained if statements.
x := 1 x := 42.0
switch x { switch x {
case 0: case 0:
case 1: case 1:
// cases don't "fall through" case 42:
case 2: // Cases don't "fall through".
// unreached case 43:
// Unreached.
} }
// Like if, for doesn't use parens either. // Like if, for doesn't use parens either.
for x := 0; x < 3; x++ { // ++ is a statement // Variables declared in for and if are local to their scope.
for x := 0; x < 3; x++ { // ++ is a statement.
fmt.Println("iteration", x) fmt.Println("iteration", x)
} }
// x == 1 here. // x == 42 here.
// For is the only loop statement in Go, but it has alternate forms. // For is the only loop statement in Go, but it has alternate forms.
for { // infinite loop for { // Infinite loop.
break // just kidding break // Just kidding.
continue // unreached continue // Unreached.
} }
// As with for, := in an if statement means to declare and assign y first, // As with for, := in an if statement means to declare and assign y first,
// then test y > x. // then test y > x.
@ -166,30 +170,17 @@ func learnFlowControl() {
} }
// Function literals are closures. // Function literals are closures.
xBig := func() bool { xBig := func() bool {
return x > 100 // references x declared above switch statement. return x > 100 // References x declared above switch statement.
} }
fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x) fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x).
x /= 1e5 // this makes it == 10 x /= m.Exp(9) // This makes x == e.
fmt.Println("xBig:", xBig()) // false now fmt.Println("xBig:", xBig()) // false now.
// When you need it, you'll love it. // When you need it, you'll love it.
goto love goto love
love: love:
// Good stuff coming up! learnInterfaces() // Good stuff coming up!
learnVariadicParams("great", "learning", "here!")
learnInterfaces()
}
// Functions can have variadic parameters
func learnVariadicParams(myStrings ...string) {
// iterate each value of the variadic
for _, param := range myStrings {
fmt.Println("param:", param)
}
// pass variadic value as a variadic parameter
fmt.Println("params:", fmt.Sprintln(myStrings...))
} }
// Define Stringer as an interface type with one method, String. // Define Stringer as an interface type with one method, String.
@ -213,16 +204,29 @@ func learnInterfaces() {
// Brace syntax is a "struct literal." It evaluates to an initialized // Brace syntax is a "struct literal." It evaluates to an initialized
// struct. The := syntax declares and initializes p to this struct. // struct. The := syntax declares and initializes p to this struct.
p := pair{3, 4} p := pair{3, 4}
fmt.Println(p.String()) // call String method of p, of type pair. fmt.Println(p.String()) // Call String method of p, of type pair.
var i Stringer // declare i of interface type Stringer. var i Stringer // Declare i of interface type Stringer.
i = p // valid because pair implements Stringer i = p // Valid because pair implements Stringer
// Call String method of i, of type Stringer. Output same as above. // Call String method of i, of type Stringer. Output same as above.
fmt.Println(i.String()) fmt.Println(i.String())
// Functions in the fmt package call the String method to ask an object // Functions in the fmt package call the String method to ask an object
// for a printable representation of itself. // for a printable representation of itself.
fmt.Println(p) // output same as above. Println calls String method. fmt.Println(p) // Output same as above. Println calls String method.
fmt.Println(i) // output same as above fmt.Println(i) // Output same as above.
learnVariadicParams("great", "learning", "here!")
}
// Functions can have variadic parameters.
func learnVariadicParams(myStrings ...interface{}) {
// Iterate each value of the variadic.
for _, param := range myStrings {
fmt.Println("param:", param)
}
// Pass variadic value as a variadic parameter.
fmt.Println("params:", fmt.Sprintln(myStrings...))
learnErrorHandling() learnErrorHandling()
} }
@ -237,7 +241,7 @@ func learnErrorHandling() {
} }
// An error value communicates not just "ok" but more about the problem. // An error value communicates not just "ok" but more about the problem.
if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
// prints "strconv.ParseInt: parsing "non-int": invalid syntax" // prints 'strconv.ParseInt: parsing "non-int": invalid syntax'
fmt.Println(err) fmt.Println(err)
} }
// We'll revisit interfaces a little later. Meanwhile, // We'll revisit interfaces a little later. Meanwhile,
@ -264,19 +268,19 @@ func learnConcurrency() {
// There is no telling in what order the results will arrive! // There is no telling in what order the results will arrive!
fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator.
cs := make(chan string) // another channel, this one handles strings. cs := make(chan string) // Another channel, this one handles strings.
cc := make(chan chan string) // a channel of string channels. ccs := make(chan chan string) // A channel of string channels.
go func() { c <- 84 }() // start a new goroutine just to send a value go func() { c <- 84 }() // Start a new goroutine just to send a value.
go func() { cs <- "wordy" }() // again, for cs this time go func() { cs <- "wordy" }() // Again, for cs this time.
// Select has syntax like a switch statement but each case involves // Select has syntax like a switch statement but each case involves
// a channel operation. It selects a case at random out of the cases // a channel operation. It selects a case at random out of the cases
// that are ready to communicate. // that are ready to communicate.
select { select {
case i := <-c: // the value received can be assigned to a variable case i := <-c: // The value received can be assigned to a variable,
fmt.Printf("it's a %T", i) fmt.Printf("it's a %T", i)
case <-cs: // or the value received can be discarded case <-cs: // or the value received can be discarded.
fmt.Println("it's a string") fmt.Println("it's a string")
case <-cc: // empty channel, not ready for communication. case <-ccs: // Empty channel, not ready for communication.
fmt.Println("didn't happen.") fmt.Println("didn't happen.")
} }
// At this point a value was taken from either c or cs. One of the two // At this point a value was taken from either c or cs. One of the two
@ -287,7 +291,7 @@ func learnConcurrency() {
// A single function from package http starts a web server. // A single function from package http starts a web server.
func learnWebProgramming() { func learnWebProgramming() {
// ListenAndServe first parameter is TCP address to listen at. // First parameter of ListenAndServe is TCP address to listen to.
// Second parameter is an interface, specifically http.Handler. // Second parameter is an interface, specifically http.Handler.
err := http.ListenAndServe(":8080", pair{}) err := http.ListenAndServe(":8080", pair{})
fmt.Println(err) // don't ignore errors fmt.Println(err) // don't ignore errors
@ -295,7 +299,7 @@ func learnWebProgramming() {
// Make pair an http.Handler by implementing its only method, ServeHTTP. // Make pair an http.Handler by implementing its only method, ServeHTTP.
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Serve data with a method of http.ResponseWriter // Serve data with a method of http.ResponseWriter.
w.Write([]byte("You learned Go in Y minutes!")) w.Write([]byte("You learned Go in Y minutes!"))
} }
``` ```