User defined function types in Go (Golang)
len() si se le pasa una cadena codificada en UTF-8?Length of string in Go (Golang).
do { ... } while i < 5
for _,c := range "hello" { ... }
for i := 1; i < 5; i++ { ... }
for i < 5 { ... }
Explicación: Go solo tiene bucles for.
values := []int{1, 1, 2}
values.append(3)
values.insert(3, 3)
append(values, 3)
values = append(values, 3)
Explicación: los slices en Go son inmutables en cuanto a tamaño; append devuelve un nuevo slice.
Read?const (
Write = iota
Read
Execute
)
import válida en Go? import "github/gin-gonic/gin"
import "https://github.com/gin-gonic/gin"
import "../template"
import "github.com/gin-gonic/gin"
package main
var GlobalFlag string
func main() {
print("["+GlobalFlag+"]")
}
GlobalFlag nunca fue inicializada.[]."[" +nil+"]" también es nil.GlobalFlag nunca fue inicializada.string es la cadena vacía.myVar si se declara fuera de cualquier función en un archivo del paquete myPackage ubicado dentro del módulo myModule?myPackage, no en el resto de myModule.myModule.myModule.myModule siempre que importen myPackage.Explicación: para hacer disponible la variable fuera de myPackage cambia el nombre a MyVar.
Consulta también un ejemplo de Exported names en el Tour of Go.
go test que imprima las pruebas que está ejecutando?go testgo test -xgo test --verbosego test -v{0, 0}. ¿Cómo lo corriges?type Point struct {
x int
y int
}
func main() {
data := []byte(`{"x":1, "y": 2}`)
var p Point
if err := json.Unmarshal(data, &p); err != nil {
fmt.Println("error: ", err)
} else {
fmt.Println(p)
}
}
json.DecoderdataX y Y exportados (mayúsculas)sync.Mutex mientras está bloqueado?Mutexint y Mutex a cada una y contar cuando regresen.select.sync.WaitGroupExplicación: esto es exactamente para lo que fue diseñado sync.WaitGroup - Use sync.WaitGroup in Golang
time.After en una sentencia select?select sin efectos secundarios.select hasta que pase el tiempo.Nota: no bloquea
selectni otros canales.
select?func Add(a, b int) int {
return a + b
}
A
// Calcula a + b
// - a: int
// - b: int
// - retorna: int
func Add(a, b int) int {
return a + b
}
B
// Hace a + b
func Add(a, b int) int {
return a + b
}
C
// Add returns the sum of a and b
func Add(a, b int) int {
return a + b
}
D
// returns the sum of a and b
func Add(a, b int) int {
return a + b
}
Explicación: el bloque de documentación debe comenzar con el nombre de la función.
myVal para compilar i := myVal.(int)?myVal debe ser un tipo entero, como int, int64, int32, etc.myVal debe poder ser afirmado como int.myVal debe ser una interfaz.myVal debe ser un tipo numérico, como float64 o int64.Explicación: Este tipo de aserción de tipos (usando .(type)) solo se usa sobre interfaces.
runtime.GOOS.// +build windows en cualquier lugar del archivo._ al nombre del archivo.// +build windows en la parte superior del archivo.
//go:build windows“Go 1.16 y anteriores usan una sintaxis diferente con el prefijo// +build.gofmtañadirá una restricción equivalente//go:buildal encontrar la sintaxis antigua.”
data := "A group of Owls is called a parliament"
resp, err := http.Post("https://httpbin.org/post", "text/plain", []byte(data))
resp, err := http.Post("https://httpbin.org/post", "text/plain", data)
resp, err := http.Post("https://httpbin.org/post", "text/plain", strings.NewReader(data))
resp, err := http.Post("https://httpbin.org/post", "text/plain", &data)
Save() error?switch _ su propio bloque léxico. Cada case _ un bloque léxico adicionalGo Language Core technology (Volume one) 1.5-scope
Extracto relevante del artículo:
El segundo
ifestá anidado dentro del primero, por lo que una variable declarada en el primerifes visible para el segundo. Hay reglas similares enswitch: cadacasetiene su propio bloque léxico además del bloque condicional.
encoding/json para Unmarshal?Extracto relevante:
Para deserializar JSON en una struct,
Unmarshalempareja las claves entrantes con el nombre del campo (o su tag), prefiriendo coincidencia exacta pero aceptando coincidencia insensible a mayúsculas.
time.Time.Sub() y time.Time.Add()?Time.Add() es para sumar y Time.Sub() para anidar timestamps.Time.Add() siempre devuelve un tiempo posterior mientras que Time.Sub siempre devuelve un tiempo anterior.Time.Add(x) equivale a Time.Sub(-x).Time.Add() acepta un Duration y devuelve un Time, mientras que Time.Sub() acepta un Time y devuelve un Duration.recover?maindeferExample of Recover Function in Go (Golang)
Extracto relevante:
recoveres útil solo cuando se llama dentro de funciones diferidas. Ejecutarrecoverdentro de una función diferida detiene la secuencia de pánico y recupera el mensaje de error pasado apanic.
println(message)log.New(os.Stderr, "", 0).Println(message)fmt.Errorf("%s\n", message)fmt.Fprintln(os.Stderr, message)replace en go.mod.go test allgo run --allgo test .go test ./...string?t.Fatal dentro de un t.Run?t.Fatal no bloquea el arnés de pruebas, preservando mensajes.t.Fatal detiene la subprueba y continúa con otros casos de prueba.t.Fatal detiene todas las pruebas e incluye información extra.log.Fatal?err)?log.Error(err)log.Printf("error: %v", err)log.Printf(log.ERROR, err)log.Print("error: %v", err)Explicación: No existe log.ERROR ni log.Error(); log.Printf() formatea como fmt.Printf().
go test como archivos de prueba?testtest_test.go_test.goch := make(chan int)
ch <- 7
val := <-ch
fmt.Println(val)
ch := make(chan int)
close(ch)
val := <-ch
fmt.Println(val)
var stocks map[string]float64 // stock -> price
price := stocks["MSFT"]
fmt.Printf("%f\n", price)
cmd y un directorio por ejecutable dentro de él.main.pkg y un directorio por ejecutable dentro de él.main.go a un ejecutable que corra en macOS arm64?Hello Gopher!?go(fmt.Println("Hello Gopher!"))go func() { fmt.Println("Hello Gopher!") }go fmt.Println("Hello Gopher!")Go fmt.Println("Hello Gopher!")map en un for range, ¿en qué orden se accederán los pares clave:valor?String() stringfunc findUser(ctx context.Context, login string) (*User, error) {
ch := make(chan *User)
go func() {
ch <- findUserInDB(login)
}()
select {
case user := <-ch:
return user, nil
case <-ctx.Done():
return nil, fmt.Errorf("timeout")
}
}
sync.WaitGroup.ch sea un canal con buffer.default al select.runtime.SetFinalizer.var i int8 = 120
i += 10
fmt.Println(i)
worker a continuación, ¿cuál es la sintaxis correcta para iniciar una goroutine que llame a worker y envíe el resultado a un canal llamado ch?func worker(m Message) Result
go func() {
r := worker(m)
ch <- r
}
go func() {
r := worker(m)
r -> ch
} ()
go func() {
r := worker(m)
ch <- r
} ()
go ch <- worker(m)
package os
type FilePermission int
type userID int
struct es otro tipo definido por el usuario que permite combinar datos de distintos tipos.type y struct.generate del compilador de Go?sql, json, yaml y opciones --schema y --objects para generar código._generate.go, y luego compila y ejecuta cada uno individualmente.//go:generate y ejecuta el comando de terminal especificado en cada uno.mocks y tests para generar archivos .go.Generate Go files by processing source
time, ¿cómo obtienes el tiempo 90 minutos desde ahora?time.Now().Add(90)time.Now() + (90 * time.Minute)time.Now() + 90time.Now().Add(90 * time.Minute)close(ch) inmediatamente después de wg.Wait().make(chan, int), p. ej. make(chan int, 5).WaitGroup, p. ej. todas las líneas que comienzan con wg.wg.Wait().encoding/json, ¿cómo accedes a la función Marshal?encoding.json.Marshalencoding/json.MarshalMarshaljson.Marshalcontext.Context e implementar un timeout de tres segundos para este cliente HTTP que realiza un GET?package main
import (
"context"
"fmt"
"net/http"
)
func main() {
var cancel context.CancelFunc
ctx := context.Background()
// #1: <=== ¿Qué va aquí?
req, _ := http.NewRequest(http.MethodGet,
"https://linkedin.com",
nil)
// #2: <=== ¿Qué va aquí?
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
fmt.Println("Request failed:", err)
return
}
fmt.Println("Response received, status code:",
res.StatusCode)
}
ctx.SetTimeout(3*time.Second)
req.AttachContext(ctx)
ctx, cancel = context.WithTimeout(ctx, 3*time.Second); defer cancel()
req = req.WithContext(ctx)
ctx, cancel = context.WithTimeout(ctx, 3*time.Second); defer cancel() #2: req.AttachContext(ctx)
ctx.SetTimeout(3*time.Second)
req = req.WithContext(ctx)
Client definida en el mismo archivo .go, ¿cómo exportas una variable con un valor por defecto para que sea accesible por otros paquetes?``````````````go let Default := new Client() ```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
``````````````
``````````````go public default = &Client() ```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
``````````````
``````````````go var Default = &Client{} ```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
``````````````
go
export default := new Client{}
```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
{Master Chief Spartan Protagonist Halo}. ¿Cómo harías para que imprima Master Chief - a Spartan - is the Protagonist of Halo?package main
import "fmt"
type Character struct{
Name string
Class string
Role string
Game string
}
func main() {
mc := Character{
Name: "Master Chief",
Class: "Spartan",
Role: "Protagonist",
Game: "Halo",
}
fmt.Println(mc)
}
A
// Reemplaza
// fmt.Println(mc)
// con esto:
fmt.Printf("(?P<Name>) - a (?P<Class>) - is the (?P<Role>) of (?P<Game>)", mc)
B
// Reemplaza
// fmt.Println(mc)
// con esto:
fmt.Println(mc, func(c Character) string {
return c. Name + " - a " + c.Class + " - is the " + c.Role + " of " + c.Game
})
C
// agrega esto al paquete `main`
func (c Character) String() string {
return fmt.Sprintf("%s - a %s - is the %s of %s", c.Name, c.Class, c.Role,c.Game)
}
D
// agrega esto al paquete `main`
func (c Character) OnPrint() {
fmt.Println(" - a - is the of ")
}
Append() funcional para Clients?package main
type Client struct {
Name string
}
type Clients struct {
clients []*Client
}
func main() {
c:= &Clients{clients.make([]*Client,0)}
c.Append(&Client{Name: "LinkedIn API})
}
A
func (cc *Clients) Append(c *Client) {
cc.clients = append(cc.clients, c)
}
B
func (cc *Clients) Append(c *Client) {
cc.append(c)
}
C
func (cc Clients) Append(c Client) {
cc.clients = append(cc.clients, c)
}
D
func (cc *Clients) Append(c Client) {
cc.clients.append(c)
}
panic() lanzado por una función llamada sin permitir que tu programa falle, asumiendo que tu respuesta se ejecute en el mismo ámbito donde ocurrirá el panic?panic y luego manejarla.try{ ... } y catch{ ... }.defer func { ... }() antes de la llamada y manejar el panic dentro de la función.@ para forzar retorno como error.var n int
fmt.Println (n)
En Go, una variable no inicializada toma su valor cero. Para
int, es 0.
String() string de un tipo personalizado?
%sformatea usando la representación de cadena; si existeString(), se invoca.
layout al llamar time.Now().Format(layout)?Namespace debe implementar la interfaz JSONConverter? (Mismo paquete que Namespace.)go
type Namespace struct {
implements JSONConverter
}
```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
go
type Namespace struct {
JSONConverter
}
```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
Esta sintaxis verifica que
*NamespacesatisfaceJSONConverter.
implements que implementa una interfaz.En Go, un tipo satisface una interfaz automáticamente si implementa todos sus métodos.
===[Output]================
1: &{GameId:1 Title:Wolfenstein YearReleased:1992}
2: &{GameId:2 Title:Doom YearReleased:1993}
3: &{GameId:3 Title:Quake YearReleased:1996}
===[main.go]================
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
type Game struct {
GameId int
Title string
YearReleased int
}
func main() {
conn, err := sql.Open("mysql",
"john_carmack:agiftw!@tcp(localhost:3306)/idsoftware")
if err != nil {
panic(err)
}
defer func() { _ = conn.Close() }()
results, err := conn.Query("SELECT game_id,title,year_released FROM games;")
if err != nil {
panic(err)
}
defer func() { _ = results.Close() }()
// #1 <=== ¿Qué va aquí?
for results.Next() {
var g Game
// #2 <=== ¿Qué va aquí?
if err != nil {
panic(err)
}
// #3 <=== ¿Qué va aquí?
}
for i, g := range games {
fmt.Printf("%d: %+v\n", i, g)
}
}
#1: games := make([]*Game, results.RowsAffected())
#2: g, err = results.Fetch()
#3: games[results.Index()] = &g
#1: games := []Game{}
#2: g, err = results.Fetch()
#3: games = append(games,g)
#1: games := map[int]Game{}
#2: err = results.Scan(&g)
#3: games[g.GameId] = g
#1: games := make(map[int]*Game, 0)
#2: err = results.Scan(&g.GameId, &g.Title, &g.YearReleased)
#3: games[g.GameId] = &g
almacenarse en un subdirectorio /test/ de ese paquete
funciones que aceptan un parámetro testing.Tester
escribiendo funciones con nombres que coincidan con ^Subtest
llamando a testing.AssertionFailed
terminar en _test.go
nombres de función que coincidan con ^Test[A-Z]
llamando a t.Run()
llamando a t.Errorf()
comenzar con test_
funciones que coincidan con [a-z]Test$
llamando a testing.Subtest()
permitiendo que testing.Assert() falle su aserción
almacenarse en el subdirectorio /test/ de la raíz del proyecto
funciones que acepten un parámetro testing.Test
pasando closures a testing.AddSubtest()
devolviendo un error desde la función
rune un alias?:= para asignar a múltiples variables? Por ejemplo:x, err := myFunc()
cpu.pprof en el navegador?go pprof -to SVG cpu.profgo tool pprof -http=:8080 cpu.pprofgo tool pprof cpu.pprofgo tool trace cpu.pprofnil una variable de tipo interface{}?nil.nil.nil.string si ha sido asignada pero no inicializada?a,b := 1, 2
b,c:= 3, 4
fmt.Println(a, b, c)
| [ ] |
funclambdafunc()anonymousfunctionName(){}call functionName(){}func(){}()execute func(){}type Example int pero no int, type Example struct{...} pero no struct, etc.struct, map y slice, p. ej. type Example struct{…}struct, p. ej. type Example struct{...}Se pueden definir métodos para cualquier tipo con nombre que no sea incorporado. reference