User defined function types in Go (Golang)
len() si on lui passe une chaîne encodée 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 { ... }
Explication : Go ne possède que des boucles for.
values := []int{1, 1, 2}
values.append(3)
values.insert(3, 3)
append(values, 3)
values = append(values, 3)
Explication : les slices en Go sont immuables, donc appeler append ne modifie pas la slice en place.
Read ?const (
Write = iota
Read
Execute
)
import valide 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 n’a jamais été initialisé.[]."[" +nil+"]" est aussi nil.GlobalFlag n’a jamais été initialisé.string, c’est la chaîne vide.myVar est-elle accessible si elle est déclarée en dehors de toute fonction dans un fichier du paquet myPackage situé dans le module myModule ?myPackage, pas dans le reste de myModule.myModule.myModule.myModule tant qu’ils importent myPackage.Explication : pour rendre la variable disponible en dehors de myPackage, changez son nom en MyVar.
Voir aussi un exemple de noms exportés dans le Tour of Go.
go test d’afficher les tests qu’il exécute ?go testgo test -xgo test --verbosego test -v{0, 0}. Comment le corriger ?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 et Y exportés (majuscules)sync.Mutex bloque pendant qu’il est verrouillé ?Mutexsync.Mutex verrouille pour qu’une seule goroutine à la fois accède à la variable protégée.int et un Mutex à chacune et compter à leur retour.select.sync.WaitGroupExplication : c’est exactement l’usage de sync.WaitGroup - Use sync.WaitGroup in Golang
time.After dans une instruction select ?select sans effets secondaires.select jusqu’à ce que le temps soit écoulé.Remarque : cela ne bloque pas
selectet ne bloque pas les autres canaux.
select ?func Add(a, b int) int {
return a + b
}
A
// Calcule a + b
// - a: int
// - b: int
// - retourne: int
func Add(a, b int) int {
return a + b
}
B
// Fait 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
}
Explication : le bloc de documentation doit commencer par le nom de la fonction.
myVal pour compiler i := myVal.(int) ?myVal doit être un type entier, tel que int, int64, int32, etc.myVal doit pouvoir être asserté comme un int.myVal doit être une interface.myVal doit être un type numérique, tel que float64 ou int64.Explication : ce type d’assertion de type (via .(type)) s’utilise uniquement sur des interfaces.
channel) ?runtime.GOOS.// +build windows n’importe où dans le fichier._ au nom du fichier.// +build windows en haut du fichier.
//go:build windows« Les versions de Go 1.16 et antérieures utilisaient une syntaxe différente pour les contraintes de build, avec le préfixe// +build. La commande gofmt ajoutera une contrainte//go:buildéquivalente en rencontrant l’ancienne syntaxe. »
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 _ son propre bloc lexical. Chaque instruction case _ un bloc lexical supplémentaireGo Language Core technology (Volume one) 1.5-scope
Extrait pertinent de l’article :
Le second
ifest imbriqué dans le premier, donc une variable déclarée dans le premierifest visible dans le second. Il y a des règles similaires dansswitch: chaquecasepossède son propre bloc lexical en plus du bloc conditionnel.
Unmarshal ?Extrait pertinent :
To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. By default, object keys which don’t have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).
Time.Sub() et Time.Add() du paquet time ?Time.Add() sert à faire des additions tandis que Time.Sub() sert à imbriquer des timestamps.Time.Add() retourne toujours un temps plus tard tandis que Time.Sub() retourne toujours un temps plus tôt.Time.Add(x) équivaut à Time.Sub(-x).Time.Add() accepte un paramètre Duration et retourne un Time tandis que Time.Sub() accepte un Time et retourne une Duration.recover est-elle utile ?maindeferred)Example of Recover Function in Go (Golang)
Extrait pertinent :
Recover is useful only when called inside deferred functions. Executing a call to recover inside a deferred function stops the panicking sequence by restoring normal execution and retrieves the error message passed to the panic function call. If recover is called outside the deferred function, it will not stop a panicking sequence.
println(message)log.New(os.Stderr, "", 0).Println(message)fmt.Errorf("%s\n", message)fmt.Fprintln(os.Stderr, message)func New(out io.Writer, prefix string, flag int) *Logger; le paramètre out définit la destination d’écriture des logs.Errorf formate selon un spécificateur et retourne la chaîne comme valeur.w.replace dans go.mod.replace.go mod edit -replace example.com/greetings=../greetings.go test allgo run --allgo test .go test ./...Extrait pertinent :
Relative patterns are also allowed, like “go test ./…” to test all subdirectories.
Extrait pertinent :
In short, Go source code is UTF-8, so the source code for the string literal is UTF-8 text.
Extrait pertinent :
Package encoding defines an interface for character encodings, such as Shift JIS and Windows 1252, that can convert to and from UTF-8.
t.Fatal diffère-t-il à l’intérieur d’un t.Run ?t.Fatal ne fait pas planter le banc de test, préservant les messages.t.Fatal arrête l’exécution du sous-test et continue avec les autres cas de test.t.Fatal arrête tous les tests et contient des informations supplémentaires sur le sous-test échoué.
Fatalis equivalent toLogfollowed byFailNow.Logformats its arguments using default formatting, analogous toPrintln, and records the text in the error log.FailNowmarks the function as having failed and stops its execution by callingruntime.Goexit(which then runs all deferred calls in the current goroutine). Execution will continue at the next test or benchmark.FailNowmust be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. CallingFailNowdoes not stop those other goroutines.Runrunsfas a subtest oftcalled name. It runsfin a separate goroutine and blocks untilfreturns or callst.Parallelto become a parallel test. Run reports whetherfsucceeded (or at least did not fail before callingt.Parallel). Run may be called simultaneously from multiple goroutines, but all such calls must return before the outer test function for t returns.
log.Fatal ?Example of func Fatal in Go (Golang)
Extrait pertinent :
Fatalis equivalent toPrint()followed by a call toos.Exit(1).
Extrait pertinent :
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)Explication : Il n’y a ni log.ERROR, ni log.Error() dans le paquet log en Go ; les arguments de log.Print() sont gérés comme fmt.Print() ; ceux de log.Printf() comme fmt.Printf().
go test reconnaît-elle comme fichiers de test ?testtest_test.go_test.go*_test.go. »ch := make(chan int)
ch <- 7
val := <-ch
fmt.Println(val)
Go Playground share, sortie :
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)
The Go Programming Language Specification “Receive operator”, extrait pertinent :
A receive operation on a closed channel can always proceed immediately, yielding the element type’s zero value after any previously sent values have been received.
Go Playground share, sortie :
0
Program exited.
var stocks map[string]float64 // stock -> price
price := stocks["MSFT"]
fmt.Printf("%f\n", price)
Go Playground share, sortie :
0.000000
Program exited.
cmd et un sous-répertoire par exécutable.main.pkg et un sous-répertoire par exécutable.main.go en un exécutable qui fonctionnera sur OSX 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, dans quel ordre les paires clé:valeur seront-elles accédées ?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 tamponné (buffered).default au select.runtime.SetFinalizer.Extrait pertinent :
The simplest way to resolve this leak is to change the channel from an unbuffered channel to a buffered channel with a capacity of 1. Now in the timeout case, after the receiver has moved on, the Goroutine will complete its send by placing the *User value in the channel then it will return.
var i int8 = 120
i += 10
fmt.Println(i)
Go Playground example, sortie :
-126
Program exited.
worker ci-dessous, quelle est la bonne syntaxe pour démarrer une goroutine qui appellera worker et enverra le résultat dans un canal nommé 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 et struct.generate du compilateur Go ?sql, json, yaml, et les options --schema et --objects pour générer le code approprié._generate.go, puis compile et exécute chacun individuellement.//go:generate et exécute pour chacun la commande terminal spécifiée.mocks et tests pour générer les fichiers .go correspondants.Generate Go files by processing source
time, comment obtenir l’heure dans 90 minutes ?time.Now().Add(90)time.Now() + (90 * time.Minute)time.Now() + 90time.Now().Add(90 * time.Minute)close(ch) immédiatement après wg.Wait().make(chan, int), par ex. make(chan int, 5).WaitGroup, par ex. toutes les lignes commençant par wg.wg.Wait().Extrait pertinent :
The simplest way to resolve this leak is to change the channel from an unbuffered channel to a buffered channel with a capacity of 1. Now in the timeout case, after the receiver has moved on, the Goroutine will complete its send by placing the *User value in the channel then it will return.
encoding/json, comment accéderiez-vous à la fonction Marshal ?encoding.json.Marshalencoding/json.MarshalMarshaljson.Marshalcontext.Context afin d’implémenter un timeout de trois secondes pour ce client HTTP effectuant une requête GET ?package main
import (
"context"
"fmt"
"net/http"
)
func main() {
var cancel context.CancelFunc
ctx := context.Background()
// #1: <=== What should go here?
req, _ := http.NewRequest(http.MethodGet,
"https://linkedin.com",
nil)
// #2: <=== What should go here?
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 définie dans le même fichier .go que l’instruction, comment exporter une variable avec une valeur par défaut pour qu’elle soit accessible par d’autres paquets ?
let Default := new Client()
public default = &Client()
var Default = &Client{}
export default := new Client{}
{Master Chief Spartan Protagonist Halo}. Comment faire pour qu’il affiche Master Chief - a Spartan - is the Protagonist of Halo à la place ?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
// Remplacez
// fmt.Println(mc)
// par :
fmt.Printf("(?P<Name>) - a (?P<Class>) - is the (?P<Role>) of (?P<Game>)", mc)
B
// Remplacez
// fmt.Println(mc)
// par :
fmt.Println(mc, func(c Character) string {
return c. Name + " - a " + c.Class + " - is the " + c.Role + " of " + c.Game
})
C
// ajoutez ceci au 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
// ajoutez ceci au package `main`
func (c Character) OnPrint() {
fmt.Println(" - a - is the of ")
}
Append() fonctionnelle pour 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() déclenché par une fonction appelée sans laisser votre programme échouer, en supposant que votre réponse s’exécute dans la même portée où l’appel de fonction provoquera le panic ?Enveloppant l’appel dans une fonction anonyme avec un type de retour panic, en n’oubliant pas de l’invoquer avec () puis en introspectant l’instance retournée pour gérer l’erreur.
Utiliser try{ ... } pour envelopper le code et gérer l’erreur dans catch{ ... }.
Utiliser defer func { ... }() avant l’appel problématique puis gérer le panic dans la fonction anonyme.
Préfixer l’appel de fonction avec @ pour forcer le retour d’un error puis le gérer comme d’habitude.
var n int
fmt.Println (n)
En Go, lorsqu’une variable est déclarée sans initialisation explicite, elle reçoit sa valeur zéro selon son type. Pour les entiers comme
n, la valeur zéro est 0.
String() string d’un type personnalisé ?En Go, le verbe %s est utilisé pour formater une chaîne. Lorsqu’il est utilisé avec un type personnalisé ayant une méthode
String(), celle-ci est appelée automatiquement et sa valeur de retour est utilisée dans la chaîne formatée.
layout lors de l’appel de time.Now().Format(layout) ?Selon la documentation, la valeur 1 et 01 représentent le mois courant.
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 doit implémenter l’interface JSONConverter ? Cette question suppose que la réponse sera incluse dans le même package où Namespace est déclarée.var _ JSONConverter = nil.(*Namespace)var _ JSONConverter = (*Namespace)(nil)go
type Namespace struct {
implements JSONConverter
}
```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
go
type Namespace struct {
JSONConverter
}
```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
Cette syntaxe crée une variable
_de typeJSONConverteret lui assigne la valeur(*Namespace)(nil). Cela vérifie queNamespacesatisfait l’interfaceJSONConverteren s’assurant qu’elle peut être affectée à une variable de typeJSONConverter.
implements que ses instances peuvent être utilisées partout où une variable, un paramètre et/ou une valeur de retour est typée pour l’interface déclarée.En Go, un type satisfait automatiquement une interface s’il implémente toutes ses méthodes. Il n’y a pas besoin de déclarer explicitement qu’une struct implémente une interface via un mot-clé spécifique.
===[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 <=== What goes here?
for results.Next() {
var g Game
// #2 <=== What goes here?
if err != nil {
panic(err)
}
// #3 <=== What goes here?
}
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
être stockés dans un sous-répertoire /test/ de ce paquet
fonctions acceptant un paramètre testing.Tester
écrire des fonctions dont le nom matche ^Subtest
appeler testing.AssertionFailed
se terminer par _test.go
noms de fonctions correspondant à ^Test[A-Z]
appeler t.Run()
appeler t.Errorf()
commencer par test_
fonctions correspondant à [a-z]Test$
appeler testing.Subtest()
laisser testing.Assert() échouer son assertion
être stockés dans le sous-dossier /test/ à la racine du projet
fonctions acceptant un paramètre testing.Test
passer des closures à testing.AddSubtest()
retourner une error depuis la fonction
rune est-il un alias ?Extrait pertinent :
The Go language defines the word rune as an alias for the type int32, so programs can be clear when an integer value represents a code point.
:= pour affecter à plusieurs variables ? Par exemple :x, err := myFunc()
cpu.pprof dans le navigateur ?go pprof -to SVG cpu.profgo tool pprof -http=:8080 cpu.pprofgo tool pprof cpu.pprofgo tool trace cpu.pprofinterface{} est-elle évaluée à nil ?nil.nil.nil.string contient-elle si elle a été allouée mais non affectée ?Si une variable string a été allouée mais non affectée, sa valeur par défaut est une chaîne vide “”. En Go, les variables non initialisées reçoivent la valeur zéro de leur type, pour les chaînes c’est “”.
panicraiseExceptionexitLa fonction intégrée utilisée pour arrêter un programme est
panic(). Lorsqu’elle est appelée, elle déclenche une panique qui interrompt le flot normal du programme. Si elle n’est pas récupérée, le programme se termine.
a,b := 1, 2
b,c:= 3, 4
fmt.Println(a, b, c)
| [ ] |
funclambdafunc()anonymousExplication : elles peuvent être définies en ligne là où elles sont utilisées, offrant plus de flexibilité d’organisation du code.
functionName(){}call functionName(){}func(){}()execute func(){}type Example int mais pas int, type Example struct{...} mais pas struct, etc.struct, map et slice, tels que type Example struct{…}struct, tels que type Example struct{...}Les méthodes peuvent être définies pour tout type nommé qui n’est pas un type intégré. Lorsqu’on crée un nouveau type via une déclaration
type, il devient un type nommé, et on peut définir des méthodes spécifiques à ce type. Les méthodes ne peuvent pas être attachées directement aux types intégrés commeint,string, etc. reference