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/