GOG - Ressources
Interfaces
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
type DatabaseMgr struct {
DB DatabaseConnector
}
type DatabaseConnector interface {
Connect(params string) string
Disconnect() bool
}
type MySQLConnector struct {
params string
}
func (mysql *MySQLConnector) Connect(params string) string {
mysql.params = params
return "MYSQL"
}
func (mysql *MySQLConnector) Disconnect() bool {
return true
}
type PostGresConnector struct {
params string
}
func (postgres *PostGresConnector) Connect(params string) string {
postgres.params = params
return "postgres"
}
func (postgres *PostGresConnector) Disconnect() bool {
return true
}
func main() {
database := &DatabaseMgr{
DB: &MySQLConnector{},
}
fmt.Println(database.DB.Connect("toto"))
database2 := &DatabaseMgr{
DB: &PostGresConnector{},
}
fmt.Println(database2.DB.Connect("toto"))
}
Errors
// You can edit this code!
// Click here and start typing.
package main
import (
"errors"
"fmt"
)
var (
ErrALessThenZero = errors.New("a est inferieur a 0")
ErrThatWillNeverShow = errors.New("will never be shown or used")
)
func OperationAvecErreur(a int) (resultat int, err error) {
if a < 0 {
return 0, ErrALessThenZero
}
return a, nil
}
func main() {
res, err := OperationAvecErreur(10)
if err != nil {
fmt.Println("erreur : ne va jamais s'afficher")
}
fmt.Println(res)
res, err = OperationAvecErreur(-1)
if err != nil {
if errors.Is(err, ErrALessThenZero) {
fmt.Println("erreur : va s'afficher")
}
if errors.Is(err, ErrThatWillNeverShow) {
fmt.Println("erreur : va jamais s'afficher")
}
}
fmt.Println(res)
}
Erreurs avec Panic
func handlePanic() {
if r := recover(); r != nil {
fmt.Println("Récupéré d’un panic:", r)
}
}
func main() {
defer handlePanic()
panic("Quelque chose s'est mal passé!")
}
Iota
// You can edit this code!
// Click here and start typing.
package main
import (
"fmt"
)
const (
A int = iota
_
B
C
)
func main() {
fmt.Println(A)
fmt.Println(B)
fmt.Println(C)
}
Select / Channels
// You can edit this code!
// Click here and start typing.
package main
import (
"fmt"
"time"
)
func routine(name string, ch_main chan string, ch_routine chan string) {
ch_main <- fmt.Sprintf("hello from %s", name)
fmt.Printf("sending to ch_routine from %s\n", name)
ch_routine <- fmt.Sprintf("hello from %s", name)
fmt.Println("name is :", name)
select {
case ch_routine_msg := <-ch_routine:
fmt.Printf("%s saw message on routine channel : %s\n", name, ch_routine_msg)
case <-time.After(time.Second):
fmt.Printf("timeout on %s\n", name)
}
time.Sleep(5 * time.Second)
ch_main <- "quit"
}
func handleSignal(ch_main chan string) {
for {
select {
case ch_main_msg := <-ch_main:
fmt.Printf("main saw message on main channel : %s\n", ch_main_msg)
if ch_main_msg == "quit" {
return
}
break
}
}
}
func main() {
ch_main := make(chan string, 1)
ch_routine := make(chan string, 1)
defer handleSignal(ch_main)
go routine("one", ch_main, ch_routine)
go routine("two", ch_main, ch_routine)
}
WaitGroup
// You can edit this code!
// Click here and start typing.
package main
import (
"fmt"
"sync"
"time"
)
func routine(name string, wg *sync.WaitGroup) {
fmt.Printf("je travaille : %s \n", name)
wg.Done()
time.Sleep(1 * time.Second)
fmt.Printf("j'ai finit : %s \n", name)
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go routine("one", &wg)
time.Sleep(2 * time.Second)
wg.Add(1)
go routine("two", &wg)
wg.Wait()
}
Mutex
// You can edit this code!
// Click here and start typing.
package main
import (
"fmt"
"sync"
"time"
)
type Info struct {
sync.Mutex
Name string
}
func routine_unsafe(name string, wg *sync.WaitGroup, info_instance *Info) {
defer wg.Done()
fmt.Printf("%s: je veux un accès a l'objet\n", name)
// pas le lock
fmt.Printf("%s: j'ai un accès a l'objet et j'ai vérouillé l'objet : je commence mon travail\n", name)
time.Sleep(3 * time.Second)
fmt.Printf("%s: info_instance actual name : %s\n", name, info_instance.Name)
fmt.Printf("%s: info_instance next name : %s\n", name, name)
info_instance.Name = name
// pas de unlock
fmt.Printf("%s: j'ai finit et relache l'objet\n", name)
}
func routine(name string, wg *sync.WaitGroup, info_instance *Info) {
defer wg.Done()
fmt.Printf("%s: je veux un accès a l'objet\n", name)
info_instance.Lock() // bloquante (si qq d'autre l'a véroillé)
fmt.Printf("%s: j'ai un accès a l'objet et j'ai vérouillé l'objet : je commence mon travail\n", name)
time.Sleep(3 * time.Second)
fmt.Printf("%s: info_instance actual name : %s\n", name, info_instance.Name)
fmt.Printf("%s: info_instance next name : %s\n", name, name)
info_instance.Name = name
fmt.Printf("%s: j'ai finit et relache l'objet\n", name)
info_instance.Unlock()
}
func main() {
var wg sync.WaitGroup
defer wg.Wait()
info_instance := &Info{
Name: "unset",
}
wg.Add(1)
go routine("one", &wg, info_instance)
wg.Add(1)
go routine("two", &wg, info_instance)
wg.Add(1)
go routine_unsafe("unsafe", &wg, info_instance)
}
Buffer
// You can edit this code!
// Click here and start typing.
package main
import (
"fmt"
"time"
)
type Info struct {
Name string
}
func routine(ch chan int) {
time.Sleep(2 * time.Second)
fmt.Println("la routine commence l'écoute ")
for {
select {
case msg := <-ch:
fmt.Println("Reçu :", msg)
case <-time.After(time.Second):
fmt.Println("Timeout atteint")
}
}
}
func main() {
//var ch chan int
ch := make(chan int)
go routine(ch)
fmt.Println("envoie de 1")
ch <- 1
fmt.Println("envoie de 2")
ch <- 2
fmt.Println("envoie de 3")
ch <- 3
fmt.Println("envoie de 4")
ch <- 4
fmt.Println("finit")
time.Sleep(5 * time.Second)
fmt.Println("done")
}
File
package main
import (
"log"
"os"
)
func main() {
f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
package main
import (
"log"
"os"
)
func main() {
err := os.WriteFile("testdata/hello", []byte("Hello, Gophers!"), 0666)
if err != nil {
log.Fatal(err)
}
}
Log
// You can edit this code!
// Click here and start typing.
package main
import (
"log"
)
func main() {
fmt.Fprintf(os.Stdout, "message\n")
fmt.Fprintf(os.Stderr, "message\n")
log.Println("test")
log.Fatal("erreur")
log.Panic("erreur")
}
Channel de channel
package main
import (
"context"
"fmt"
"os"
"os/signal"
"time"
)
func handleChan(ch chan string) {
for {
select {
case msg := <-ch:
fmt.Println(msg)
case <-time.After(10 * time.Second):
return
}
}
}
func createDynamicChan(buffer int, bigchan chan chan string) chan string {
ch := make(chan string, 10)
bigchan <- ch
return ch
}
func sendMsg(ch chan string, msg string) {
ch <- msg
}
func highlevel(bigchan chan chan string) {
localch := createDynamicChan(10, bigchan)
for i := 0; i < 10; i++ {
sendMsg(localch, fmt.Sprintf("%d \n", i))
}
}
func handleWorker(bigchan chan chan string, ctx context.Context) {
for {
select {
case ch := <-bigchan:
go handleChan(ch)
case <-ctx.Done():
return
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt)
bigchan := make(chan chan string, 10)
go handleWorker(bigchan, ctx)
go highlevel(bigchan)
go highlevel(bigchan)
time.Sleep(10 * time.Second)
cancel()
fmt.Println("done")
}
TP Avancé
GOG - Practice
Mise en place GORM go get -u gorm.io/gorm
go get -u gorm.io/driver/postgres package main import ( “fmt” “gorm.io/driver/postgres” “gorm.io/gorm” “log”
) var DB *gorm.DB func initDatabase() { dsn := “host=localhost user=gormuser password=gormpassword dbname=gormdb port=5432 sslmode=disable TimeZone=Europe/
