Le langage Go

Le langage Go est un langage de programmation multi-paradigme, intégrant des styles de la programmation impérative, parallèle, logique, fonctionnelle, objet. C'est un langage orienté objet, mais sans hierarchie de classe, il utilise des interfaces. Le langage est compilé avec typage statique des varables, Le langage Go a un système de type statique, fortement typé, structurel et sûr, basé sur l'inférence de types avec la possibilité d'utiliser un typage explicite. Il est multi-thread.

Le langage Go est inspiré du C et du Pascal, facile à comprendre et facile à adopter. La compilation du Go est trés rapide. La rapidité d'exécution est aussi visée, égale à celle du C. Il peut être utilisé aussi bien pour écrire des applications, des scripts ou de grands systèmes. Sa simplicité est voulue pour assurer la maintenance et l'évolution des programmes sur plusieurs générations de développeurs.

Dans le langage Go, la gestion de la mémoire est laissée à un ramasse-miette.

Ce langage a été conçu initialement par Keith Clark et Francis McCabe sous le nom de Go! en 2003, puis développé en open-source libre par Google en 2009 à partir d'une conception de Robert Griesemer, Rob Pike et Ken Thompson.

Documents : golang-france | go-par-l-exemple.pdf

(A remarquer, le grand nombre de caractères qui peut être utilisés pour programmer, comprenant lettres grecs, lettre accentués, caractères chinois, etc.. Cela permet de réduire la taille des noms de variable et des noms de fonctions et d'obtenir ainsi un code beaucoup plus lisible.)

1) Installation

1- Installez gedit. C'est un éditeur de texte trés pratiques avec coloration syntaxique pour de nombreux langages dont go :

apt-get install gedit

2- Installez git. Cela nous sera utile pour télécharger les outils :

apt-get install git 

3- Installez go. Sur Ubuntu tapez la commande suivante en étant root :

apt-get install golang

4- Créer un répertoire go dans votre répertoire personnel et créer le répertoire go/bin. Cela servira pour télécharger les outils. C'est votre espace de travail en plus de celui qui va être installé par eclipse.

5- Testez votre compilateur go. Créer un répertoire go/hello et un fichier /go/hello/hello.go dans le quel vous écrivez ceci :

package main
import "fmt"
func main() {
     fmt.Println("Bonjour le Monde ! \n" )
   }

Placez vous dans le répertoire /go/hello/ et tapez la commande suivante :

 go build

Cela compile les programmes présent dans le répertoire et donc cela compile hello.go et cela crée un executable hello, que vous pouvez lancer en tapant

.\hello
Bonjour le Monde !   

6- Déterminer où se trouve le compilateur go. Tapez la commande

 type go 

Vous aurez une réponse du genre : go est /usr/bin/go. dans ce cas le chemin d'installation est /usr. Celui ci contient un dossier bin qui contient le binaire go.

7- Installer un Java VM version 8 ou plus

8- Télécharger Eclipse IDE for C/C++ Developpers à partir du site https://www.eclipse.org/downloads/eclipse-packages/ . Décompressez-le et placez le dossier complet dans votre répertoire personnel en le renommant eclipse.

9- Installer Goclipse. Lancez l'application eclipse par un double click sur eclipse/eclipse
Help | Install New Software... Cliquez Add, puis entrez le site de mise à jour http://goclipse.github.io/releases/ et faire ok, suivant, terminer.
Redémarez eclipse.
Par la suite, pour les mise à jour, faites : Help | Check for Updates...

10- Paramètrer les préférense d'eclipse.
On n'exporte pas de variable d'environnement GOPATH et GOROOT
Lancez l'application eclipse.
Windows | Preferences
>Go>Tools : gofmt : "Executable:" = /usr/bin/gofmt, Bouton Apply
>Go : "Go Installation" = /usr
Décochez "Use same value as the GOPATH environnement variable
"Eclipse GOPATH" = :/home/dmabboux/go
Cochez "Also add projet location to GOPATH"
>Go>Tools : :
gocode : Download,
guru : Doxnload,
godef : Download,
gofmt : Cochez "Use default location (from go installation)"
Cochez "Format automatically on editor save"
Bouton Apply and close

11-Installer le framework SDL2, tapez la commande suivante en étant root :

apt-get install libsdl2{,-mixer,-image,-ttf}-dev

12- Télecharger le package sdl (utilisé par les programmes go contenant l'instruction import "github.com/veandco/go-sdl2/sdl")
On crée momentanément une variable d'environnement GOPATH.

export GOPATH=/home/martin/go
go get -v github.com/veandco/go-sdl2/sdl
go get -v github.com/veandco/go-sdl2/mix
go get -v github.com/veandco/go-sdl2/img
go get -v github.com/veandco/go-sdl2/ttf

13- Testez le package sdl.

package main
import "github.com/veandco/go-sdl2/sdl"
func main() {
   sdl.Init(sdl.INIT_EVERYTHING)
   W,_:= sdl.CreateWindow("test", 0, 0, 800, 600, sdl.WINDOW_SHOWN)
   defer W.Destroy()
   O,_:= W.GetSurface()
   r := sdl.Rect{0, 0, 200, 200}
   O.FillRect(&r, 0xffff0000)
   W.UpdateSurface()
   sdl.Delay(1000)
   sdl.Quit()
}


 

---- Août 2017 ----

 

  

2) Premier exemple exploitant les facilités du ramasse-miette

La gestion des pointeurs et de la mémoire dans Go est simplifier par un système intégré de ramasse-miette qui libére les mémoires occupés rendues inaccessibles. Cela nous permet de programmer des algorithmes sur les graphes sans avoir à nous préoccuper de libérer les mémoires perdues.

On se propose de construire un monoïde à partir de sa présentation tel que par exemple :

`"<"a,b">" "/" {aaaa=1,bbbb=1,ab=ba}`

Le monoïde est mémorisé sous forme d'un graphe orienté où chaqe noeuds est identifié à un éléments du monoïde `x`, et où chaque arc est labellisé par un élément générateur `a` ou `b`. La racine du graphe est l'élément neutre `1`. Chaque noeud `x` possède deux fils, `xa` et `xb`, qui sont les éléments resultats du produit dans le monoïde avec les éléments générateurs respectifs `a` et `b`.

package main
import (
 "fmt"
 "os"
   )
type Cell struct {
    f1 uint8
    T *Cell
    A, B *Cell
}
var mp uint8 = 0
var N int
var O *Cell = &Cell{mp, nil, nil, nil}
var flag bool = true

"fmt" : L'import fmt est utilisé pour la fontion fmt.Print() qui imprime sur la consol.
"os" : L'import os est utlisé pour l'acces à os.Args qui contient la liste des arguments de type []string passée en ligne de commade.

Un sommet d'un graphe orienté est une racine si et seulement si tous les sommets du graphes sont atteignables en respectant le sens des arcs, en partant du sommet en question.

f1 : Pour parcourir un graphe de façon récurcive à partir d'une racine, il faut marquer les sommets à partir des quels on a lancé la procédure récurcive de parcours afin que si on revient au même endroit on ne relance pas le parcours. On marque en positionnant f1 à 1-md.

T : Désigne un autre noeud du graphe créé plus récemment. Cela se produit dans les cas de fusions.

A, B : Désigne les deux fils.

mp : Désigne le mode de passage, l'état du flag f1 des noeuds non encore parcourus.

N : descompte des noeuds du graphe.

O : Racine du graphe, correspond à l'élément neutre du monoïde.

flag : Indique qu'une modification s'est produite dans le graphe et qu'il faux donc continuer à appliquer les égalités de chemin pour les noeuds de la génération suivante.

func A(x *Cell) *Cell {
if x.A == nil {
y := &Cell{mp, nil, nil, nil}
x.A = y
} else {
for ; x.A.T != nil; x.A = x.A.T {
}
}
return x.A
} func B(x *Cell) *Cell {
if x.B == nil {
y := &Cell{mp, nil, nil, nil}
x.B = y
} else {
for ; x.B.T != nil; x.B = x.B.T {
}
}
return x.B
}

A(x) : déplace vers le fils selon l'arc "a". Si ce noeuds est transféré suivre la suite des transfères et redirigé le fils directement sur ce transfère. Si le noeud n'existe pas alors le créer et redirigé le fils dessus.

B(x) : déplace vers le fils selon l'arc "b" et si ce noeuds est transféré suivre la suite des transfères et redirigé le fils directement sur ce transfère.Si le noeud n'existe pas alors le créer et redirigé le fils dessus.

func fusion(x *Cell, eq string) {
var x1, x2 *Cell
z := x
for _, v := range eq {
switch v {
case 'a':
z = A(z)
case 'b':
z = B(z)
case '1':
case '=':
x1 = z
z = x
}
x2 = z
}
if x1 != x2 {
flag = true
x1.T = x2
}
} func fusions(x *Cell, L []string) {
for i, v := range L {
if i == 0 {
} else {
fusion(x, v)
}
}
}

fusion(x, "abaa=abb") : En partant de x fusionne les deux chemins "abaa" et "abb" en mettant le lien transfère du premier vers le second.

fusions(x, {"ab=ba", "aab=1", "bba=b"}) : Execute fusion(x, eq) pour chaque string eq du tableau de string.

 

 

 

 

 

---- 20 juillet 2017 ----

 

 

 

 


Dominique Mabboux-Stromberg