Programmation Go
Go est un langage de programmation développé par Google, connu pour sa simplicité et sa performance. Il est utilisé pour le développement de logiciels, d'applications web et de systèmes d'exploitation.
Apprendre Go
- Tour de Go : explorez les fonctionnalités de base du langage Go et notez ses caractéristiques uniques.
- En supplément Concepts de Go avec des exemples
- Création d'une CLI avec Go
- Développement web en Go
Questions
- Quel est l'intérêt du package main en Go ?
- Quelle est la différence entre
:=
et=
en Go ? - Quelle est la différence entre
var
etconst
en Go ? - Quelle est la différence entre
nil
etnull
en Go ? - Quelle est la différence entre
panic
eterror
en Go ? - Quel style d'import est préférable entre imports multiples et une seul import groupé ?
- Comment exporter un identifiant en Go ?
- En Go, le type vient avant ou après le nom de la variable ?
- Que singifie une naked return (ou return nu) en Go ?
- Dans quel unique endroit peut-on utiliser := ?
- Est-ce que Go autorise la conversion implicite de types ?
- Combien de types de boucles en Go connaissez-vous ? Quels sont-ils ?
- Est-ce Go autorise les switch sans condition (ou sans expression après le switch) ?
- Quelle est la différence entre
[n]T
et[]T
en Go ? - Est-ce qu'un slice est un nouveau tableau ?
- Que font
make
etappend
en Go ? - Est-ce que
append
retourne un nouveau slice ou modifie le slice existant ? - Qu'est-ce qu'une closure en Go ?
- Est-ce que Go a des classes ? Si oui, expliquez comment elles fonctionnent. Sinon, expliquer les alternatives.
- Quelle est la différence entre une un méthode et une fonction en Go ?
- Quelles la différence entre un méthode avec un receveur de type pointeur et un receveur de type valeur ?
- Est-ce que Go renvoie une NPE quand on appelle une méthode d'une interface nulle ?
- A quoi servent les formateurs %v, %T, %s et %d ?
- Expliquer comment gérer les erreurs en Go. Est-ce que Go a des exceptions ?
Réponses
- Le package
main
est le point d'entrée d'une application Go. :=
est utilisé pour déclarer et initialiser une variable, tandis que=
assigne une valeur à une variable déjà déclarée.var
déclare une variable, alors queconst
déclare une constante.nil
est utilisé en Go pour désigner l'absence de valeur pour les types de référence,null
étant un concept non applicable en Go.panic
est un état d'erreur fatale qui entraîne l'arrêt du programme, alors qu'error
est une interface qui peut être gérée.- Il est préférable d'utiliser un import groupé pour améliorer la lisibilité du code.
- Pour exporter un identifiant en Go, il doit commencer par une majuscule.
- En Go, le type vient après le nom de la variable.
- Une naked return est une instruction de retour sans argument, qui retourne les valeurs des variables de retour nommées.
- On ne peut utiliser
:=
que dans une fonction. - Go n'autorise pas la conversion implicite de types.
- Il existe un seul type de boucles en Go qui est la boucle
for
. - Go autorise les switch sans condition, qui permettent de simplifier les conditions multiples.
[n]T
est un tableau de taille fixe, tandis que[]T
est une tranche de taille variable.- Un slice est une vue sur un tableau ou un pointeur vers celui-ci.
make
est utilisé pour créer des slices, des maps et des channels, tandis queappend
est utilisé pour ajouter des éléments à un slice.append
retourne un nouveau slice si la capacité du slice est dépassée, sinon il modifie le slice existant.- Une closure est une fonction qui capture les variables de son environnement.
- Go n'a pas de classes, mais utilise des structures pour définir des types de données et des méthodes associées, en plus des interfaces pour définir des comportements communs.
- Une méthode est une fonction associée à un type, qui peut être appelée sur une instance de ce type.
- Une méthode avec un receveur de type pointeur modifie la valeur de l'instance, tandis qu'un receveur de type valeur crée une copie de l'instance.
- Go ne renvoie pas de NPE et appelle la méthode avec un receveur nul si elle a un type concret. Néanmoins, si l'interface n'a pas type concret, l'appel de la méthode entraînera une panique.
%v
affiche la valeur de la variable,%T
affiche le type de la variable,%s
affiche la chaîne de caractères et%d
affiche un entier.- Les erreurs en Go sont gérées en retournant une valeur d'erreur en plus de la valeur de retour, qui peut être vérifiée et traitée par l'appelant. Go n'a pas d'exceptions, mais utilise des valeurs d'erreur pour signaler les erreurs.
Quelques programmes
Sqrt
package main
import (
"fmt"
"math"
)
func Sqrt(x float64) float64 {
z := 1.0
previousZ := 0.0
epsilon := 0.000001
for i := 0; i < 10 && math.Abs(previousZ-z) > epsilon; i++ {
previousZ = z
z -= (z*z - x) / (2 * z)
fmt.Println(z)
}
return z
}
func main() {
fmt.Println(Sqrt(2), math.Sqrt(2))
fmt.Println(Sqrt(9), math.Sqrt(9))
}
pic
A lancer depuis l'éditeur en ligne pour avoir un rendu graphique.
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
columns := make([][]uint8, dx)
for x := 0; x < dx; x++ {
row := make([]uint8, dy)
for y := 0; y < dy; y++ {
row[y] = uint8((x + y) / 2)
// row[y] = uint8(x ^ y)
}
columns[x] = row
}
return columns
}
func main() {
pic.Show(Pic)
}
wordcount
/*
Implement WordCount. It should return a map of the counts of each “word” in the string s.
The wc.Test function runs a test suite against the provided function and prints success or failure.
You might find strings.Fields helpful.
*/
package main
import (
"strings"
"golang.org/x/tour/wc"
)
func WordCount(s string) map[string]int {
counts := make(map[string]int)
for _, word := range strings.Fields(s) {
counts[word] = counts[word] + 1
}
return counts
}
func main() {
wc.Test(WordCount)
}
fibclosure
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
nm1 := 0
nm2 := 0
return func() int {
n := nm1 + nm2
nm2 = nm1
nm1 = n
if n == 0 {
nm2 = 1
}
return n
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
stringerdemo
package main
import (
"fmt"
"strconv"
"strings"
)
type IPAddr [4]byte
func (ipAddr IPAddr) String() string {
// Slice of length 0 and capacity 4 (size of array)
s := make([]string, 0, len(ipAddr))
for _, v := range ipAddr {
s = append(s, strconv.Itoa(int(v)))
}
return strings.Join(s, ".")
}
func main() {
hosts := map[string]IPAddr{
"loopback": {127, 0, 0, 1},
"googleDNS": {8, 8, 8, 8},
}
for name, ip := range hosts {
fmt.Printf("%v: %v\n", name, ip)
}
}
rot13reader
/*
source: https://go.dev/tour/methods/23
A common pattern is an io.Reader that wraps another io.Reader, modifying the stream in some way.
For example, the gzip.NewReader function takes an io.Reader (a stream of compressed data) and returns a *gzip.Reader that also implements io.Reader (a stream of the decompressed data).
Implement a rot13Reader that implements io.Reader and reads from an io.Reader, modifying the stream by applying the rot13 substitution cipher to all alphabetical characters.
The rot13Reader type is provided for you. Make it an io.Reader by implementing its Read method.
*/
package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func (r rot13Reader) Read(b []byte) (int, error) {
n, err := r.r.Read(b)
if err != nil {
return 0, err
}
for i := range n {
if b[i] < 'A' || b[i] > 'z' || (b[i] > 'Z' && b[i] < 'a') {
continue
}
middleLetter := 'M'
if b[i] >= 'a' {
middleLetter = 'm'
}
if b[i] > byte(middleLetter) {
b[i] -= 13
} else {
b[i] += 13
}
}
return n, nil
}
func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}