User defined function types in Go (Golang)
len() se le viene passata una stringa codificata in 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 { ... }
Spiegazione: Go ha solo cicli for.
values := []int{1, 1, 2}
values.append(3)
values.insert(3, 3)
append(values, 3)
values = append(values, 3)
Spiegazione: le slice in Go sono immutabili, quindi chiamare append non modifica la slice.
Read?const (
Write = iota
Read
Execute
)
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 non è mai stata inizializzata.[]."[" +nil+"]" è anche nil.GlobalFlag non è mai stata inizializzata.myVar se è dichiarata fuori da qualsiasi funzione in un file nel package myPackage dentro il modulo myModule?myPackage, non nel resto di myModule.myModule.myModule.myModule se importano myPackage.Spiegazione: per rendere la variabile disponibile fuori da myPackage cambia il nome in MyVar.
Vedi anche un esempio di Exported names nel Tour of Go.
go test di stampare i test che sta eseguendo?go testgo test -xgo test --verbosego test -v{0, 0}. Come lo correggi?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 e Y esportate (maiuscole)sync.Mutex mentre è bloccato (locked)?Mutexsync.Mutex blocca in modo che solo una goroutine alla volta possa accedere alla variabile protetta.int e un Mutex a ciascuna e contare quando ritornano.select.sync.WaitGroupSpiegazione: è esattamente per questo che è progettato sync.WaitGroup - Use sync.WaitGroup in Golang
time.After in uno statement select?select finché il tempo non è passato.Nota: non blocca
selecte non blocca altri canali.
select?func Add(a, b int) int {
return a + b
}
A
// Calculate a + b
// - a: int
// - b: int
// - returns: int
func Add(a, b int) int {
return a + b
}
B
// Does 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
}
Spiegazione: il blocco di documentazione dovrebbe iniziare con il nome della funzione.
myVal per compilare i := myVal.(int)?myVal deve essere un tipo intero, come int, int64, int32, ecc.myVal deve poter essere asserito come int.myVal deve essere un’interfaccia.myVal deve essere un tipo numerico, come float64 o int64.Spiegazione: Questo tipo di casting (usando .(type)) si usa solo sulle interfacce.
runtime.GOOS.// +build windows in qualsiasi punto del file._ al nome del file.// +build windows all’inizio del file.
//go:build windows“Go versions 1.16 and earlier used a different syntax for build constraints, with a “// +build” prefix. The gofmt command will add an equivalent //go:build constraint when encountering the older syntax.”
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 _ il proprio blocco lessicale. Ogni istruzione case _ un blocco lessicale aggiuntivoGo Language Core technology (Volume one) 1.5-scope
Estratto rilevante dall’articolo:
La seconda istruzione if è annidata dentro la prima, quindi una variabile dichiarata nella prima è visibile alla seconda. Regole simili in switch: ogni case ha il proprio blocco lessicale oltre al blocco condizionale.
Unmarshal?Estratto rilevante dall’articolo:
Per deserializzare JSON in una struct, Unmarshal associa le chiavi dell’oggetto in ingresso alle chiavi usate da Marshal (il nome del campo struct o il suo tag), preferendo una corrispondenza esatta ma accettando anche una corrispondenza case-insensitive. Per impostazione predefinita, le chiavi senza campo corrispondente vengono ignorate (vedi Decoder.DisallowUnknownFields per un’alternativa).
Time.Sub() e Time.Add() del package time?Duration e restituisce un Time mentre Time.Sub() accetta un Time e restituisce una Duration.recover?maindeferred)Example of Recover Function in Go (Golang)
Estratto rilevante dall’articolo:
recoverè utile solo quando chiamato dentro funzioni differite. Eseguirerecoverdentro una funzione differita interrompe la sequenza di panic ripristinando l’esecuzione normale e recupera il messaggio di errore passato apanic. Se chiamato fuori da una funzione differita, non interrompe il panic.
println(message)log.New(os.Stderr, "", 0).Println(message)fmt.Errorf("%s\n", message)fmt.Fprintln(os.Stderr, message)replace in go.mod.replace.go mod edit -replace example.com/greetings=../greetings.go test allgo run --allgo test .go test ./...Estratto rilevante dall’articolo:
Sono consentiti anche pattern relativi, come “go test ./…” per testare tutte le sottodirectory.
Estratto rilevante dall’articolo:
In breve, il codice sorgente Go è UTF-8, quindi il letterale di stringa è testo UTF-8.
Estratto rilevante dall’articolo:
Il package encoding definisce un’interfaccia per le codifiche di caratteri che possono convertire da e verso UTF-8.
t.Fatal dentro un t.Run?t.Fatal non blocca il test harness, preservando i messaggi di output.t.Fatal ferma l’esecuzione del sotto-test e continua con gli altri test.t.Fatal ferma tutti i test e contiene info extra sul sotto-test fallito.
Fatalè equivalente aLogseguito daFailNow… l’esecuzione continuerà al prossimo test o benchmark.
log.Fatal?Example of func Fatal in Go (Golang)
Estratto rilevante:
Fatalè equivalente aPrint()seguito daos.Exit(1).
Estratto rilevante:
Year: "2006" "06"
Month: "Jan" "January" "01" "1"
Day of the week: "Mon" "Monday"
Day of the month: "2" "_2" "02"
Day of the year: "__2" "002"
Hour: "15" "3" "03" (PM or AM)
Minute: "4" "04"
Second: "5" "05"
AM/PM mark: "PM"
err)log.Error(err)log.Printf("error: %v", err)log.Printf(log.ERROR, err)log.Print("error: %v", err)Spiegazione: Non esistono né log.ERROR né log.Error() nel package log di Go; log.Print() gestisce gli argomenti come fmt.Print(); log.Printf() come fmt.Printf().
go test riconosce come file di test?testtest_test.go_test.goch := make(chan int)
ch <- 7
val := <-ch
fmt.Println(val)
Go Playground share, output:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/tmp/sandbox2282523250/prog.go:7 +0x37
Program exited.
ch := make(chan int)
close(ch)
val := <-ch
fmt.Println(val)
0
Program exited.
var stocks map[string]float64 // stock -> price
price := stocks["MSFT"]
fmt.Printf("%f\n", price)
Go Playground share, output:
0.000000
Program exited.
cmd e una directory per eseguibile al suo interno.main.pkg e una directory per eseguibile al suo interno.main.go in un eseguibile che girerà su macOS arm64?print Hello Gopher!?go(fmt.Println("Hello Gopher!"))go func() { fmt.Println("Hello Gopher!") }go fmt.Println("Hello Gopher!")Go fmt.Println("Hello Gopher!")for range, in che ordine verranno accessi i pair chiave:valore?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 un canale bufferizzato.default al select.runtime.SetFinalizer.Estratto rilevante:
Il modo più semplice per risolvere questa perdita è cambiare il canale da non bufferizzato a bufferizzato con capacità 1…
var i int8 = 120
i += 10
fmt.Println(i)
-126
Program exited.
worker sotto, qual è la sintassi corretta per avviare una goroutine che chiamerà worker e invierà il risultato su un canale 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
type e struct.generate del compilatore Go?sql, json, yaml, e opzioni --schema e --objects per generare codice._generate.go, poi compila ed esegue ciascuno di essi.//go:generate e per ciascuno esegue il comando di terminale specificato.mocks e tests per generare file .go.Generate Go files by processing source
time, come puoi ottenere l’ora tra 90 minuti da adesso?time.Now().Add(90)time.Now() + (90 * time.Minute)time.Now() + 90time.Now().Add(90 * time.Minute)close(ch) immediatamente dopo wg.Wait().make(chan, int), es. make(chan int, 5).WaitGroup (tutte le righe che iniziano con wg).wg.Wait().Estratto rilevante:
Il modo più semplice per risolvere questa perdita è cambiare il canale da non bufferizzato a bufferizzato con capacità 1…
encoding/json, come accederai alla funzione Marshal?encoding.json.Marshalencoding/json.MarshalMarshaljson.Marshalcontext.Context e implementare un timeout di 3 secondi per un client HTTP che fa una GET?package main
import (
"context"
"fmt"
"net/http"
)
func main() {
var cancel context.CancelFunc
ctx := context.Background()
// #1: <=== Cosa va qui?
req, _ := http.NewRequest(http.MethodGet,
"https://linkedin.com",
nil)
// #2: <=== Cosa va qui?
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 definita nello stesso file .go dell’istruzione, come esporti una variabile con un valore di default in modo che sia accessibile dagli altri package?
let Default := new Client()
public default = &Client()
var Default = &Client{}
export default := new Client{}
{Master Chief Spartan Protagonist Halo}. Come faresti ad ottenere Master Chief - a Spartan - is the Protagonist of Halo invece?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
// Replace
// fmt.Println(mc)
// with this:
fmt.Printf("(?P<Name>) - a (?P<Class>) - is the (?P<Role>) of (?P<Game>)", mc)
B
// Replace
// fmt.Println(mc)
// with this:
fmt.Println(mc, func(c Character) string {
return c. Name + " - a " + c.Class + " - is the " + c.Role + " of " + c.Game
})
C
// add this to the package `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
// add this to the package `main`
func (c Character) OnPrint() {
fmt.Println(" - a - is the of ")
}
Append() funzionante per 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() lanciato da una funzione chiamata senza permettere che il programma fallisca, assumendo che la risposta giri nello stesso scope in cui avviene il panic?panic, ricordando di invocarla con () e gestendo l’errore.try{ ... } e poi gestisci l’errore nel catch{ ... }.defer func { ... }() prima della chiamata e gestisci il panic dentro la funzione anonima.@ per forzare il ritorno del panic come error.var n int
fmt.Println (n)
Questo perché in Go, quando una variabile è dichiarata ma non inizializzata, riceve il valore zero del suo tipo. Per gli interi come
n, è 0.
String() string di un tipo custom?In Go, il verb
%sformatta una stringa. Con un tipo che haString(), verrà chiamato automaticamente e usato il suo valore di ritorno.
layout chiamando time.Now().Format(layout)?Secondo la documentazione, i valori 1 e 01 rappresentano il mese corrente.
each layout string is a representation of the time stamp,
Jan 2 15:04:05 2006 MST
An easy way to remember this value is that it holds, when presented in this order, the values (lined up with the elements above):
1 2 3 4 5 6 -7
Namespace deve implementare l’interfaccia JSONConverter? Si assume che la risposta sia nello stesso package di Namespace.Questa sintassi crea una variabile
_di tipoJSONConvertere le assegna(*Namespace)(nil). In pratica verifica cheNamespacesoddisfi l’interfaccia.
In Go, un tipo soddisfa un’interfaccia automaticamente se implementa tutti i metodi. Non c’è keyword per dichiararlo.
===[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 <=== Cosa va qui?
for results.Next() {
var g Game
// #2 <=== Cosa va qui?
if err != nil {
panic(err)
}
// #3 <=== Cosa va qui?
}
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
#- [x]
#1: games := make(map[int]*Game, 0)
#2: err = results.Scan(&g.GameId, &g.Title, &g.YearReleased)
#3: games[g.GameId] = &g
essere memorizzati in una sottodirectory /test/ di quel package
funzioni che accettano un parametro testing.Tester
scrivendo funzioni con nomi che combaciano con ^Subtest
chiamando testing.AssertionFailed
finire in _test.go
nomi funzione che combaciano con ^Test[A-Z]
chiamando t.Run()
chiamando t.Errorf()
iniziare con test_
funzioni che combaciano con [a-z]Test$
chiamando testing.Subtest()
permettendo a testing.Assert() di fallire l’asserzione
essere memorizzati nella root /test/ del progetto
funzioni che accettano un parametro testing.Test
passando closure a testing.AddSubtest()
restituendo un error dalla funzione
rune?Estratto rilevante:
Go definisce la parola rune come alias per
int32, così i programmi possono essere chiari quando un intero rappresenta un code point.
:= per assegnare a più variabili? Per esempio:x, err := myFunc()
cpu.pprof nel browser?go pprof -to SVG cpu.profgo tool pprof -http=:8080 cpu.pprofgo tool pprof cpu.pprofgo tool trace cpu.pprofinterface{} valuta a nil?nil.nil.nil.Se una string è allocata ma non assegnata, il suo valore di default è la stringa vuota “”. In Go, le variabili string non inizializzate ricevono il valore zero del tipo.
panicraiseExceptionexitLa funzione built-in per fermare l’esecuzione è
panic(). Se non viene recuperata, il programma termina.
a,b := 1, 2
b,c:= 3, 4
fmt.Println(a, b, c)
| [ ] |
funclambdafunc()anonymousSpiegazione: possono essere definite inline dove sono usate, offrendo maggiore flessibilità nell’organizzazione del codice.
functionName(){}call functionName(){}func(){}()execute func(){}type Example int ma non int, type Example struct{...} ma non struct, ecc.type Example struct{…}type Example struct{...}I metodi possono essere definiti per qualsiasi tipo con nome che non sia built-in. Non possono essere attaccati direttamente a tipi built-in come
int,string, ecc. reference