le langage go 2ème partie
DESCRIPTION
Le langage Go 2ème partie. Rob Pike [email protected] Traduction en français, adaptation xavier.mehaut @ gmail.com (Version de Juin 2011). Sommaire de la journée. Exercices des questions? Types composite structures, arrays , slices, maps Méthodes - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/1.jpg)
Le langage Go
2egraveme partie
Rob Pikergooglecom
Traduction en franccedilais adaptation xaviermehaut gmailcom
(Version de Juin 2011)
Sommaire de la journeacutee
Exercicesdes questions
Types compositestructures arrays slices maps
Meacutethodestheyre not just for structs any more
Interfaces
Exercices
Des questions
Tableaux
Tableaux (arrays)Les tableaux en Go sont quelque peu diffeacuterents de ceux en C plus comme des tableaux en Pascal (Slices le prochain sujet se comportent un peu plus comme des tableaux C)
var ar [3]int deacuteclares ar comme eacutetant un tableau de 3 entiers initialiseacutes agrave zeacutero
La taille fait partie du type
La fonction native len renvoie la taille len(ar) == 3
Les tableaux sont des valeursLes tableaux sont des valeurs pas des pointeurs implicites comme en C Vous pouvez reacutecupeacuterer lrsquoadresse drsquoun tableau attribuer un pointeur agrave un tableau (par exemple pour le passer efficacement sans recopie agrave une fonction)
func f(a [3]int) fmtPrintln(a) func fp(a [3]int) fmtPrintln(a) func main()
var ar [3] intf(ar) passe une copie de arfp(ampar) passe un pointeur sur ar
Sortie(Print et consors reconnaissent les tableaux) [0 0 0]amp[0 0 0]
Les liteacuteraux tableauTous les types composite ont une syntaxe similaire pour la creacuteation des valeurs Pour les tableaux cela ressemble agrave
Tableau de 3 entiers[3]int1 2 3
Tableau de 10 entiers les trois premiers nrsquoeacutetant pas agrave zeacutero[10]int 1 2 3
Vous ne voulez pas compter Utilisez pour la initialiser la longueur[]int1 2 3
Vous ne voulez pas tous les initialiser Utilisez les paires keyvalue [10]int21 31 51 71
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 2: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/2.jpg)
Sommaire de la journeacutee
Exercicesdes questions
Types compositestructures arrays slices maps
Meacutethodestheyre not just for structs any more
Interfaces
Exercices
Des questions
Tableaux
Tableaux (arrays)Les tableaux en Go sont quelque peu diffeacuterents de ceux en C plus comme des tableaux en Pascal (Slices le prochain sujet se comportent un peu plus comme des tableaux C)
var ar [3]int deacuteclares ar comme eacutetant un tableau de 3 entiers initialiseacutes agrave zeacutero
La taille fait partie du type
La fonction native len renvoie la taille len(ar) == 3
Les tableaux sont des valeursLes tableaux sont des valeurs pas des pointeurs implicites comme en C Vous pouvez reacutecupeacuterer lrsquoadresse drsquoun tableau attribuer un pointeur agrave un tableau (par exemple pour le passer efficacement sans recopie agrave une fonction)
func f(a [3]int) fmtPrintln(a) func fp(a [3]int) fmtPrintln(a) func main()
var ar [3] intf(ar) passe une copie de arfp(ampar) passe un pointeur sur ar
Sortie(Print et consors reconnaissent les tableaux) [0 0 0]amp[0 0 0]
Les liteacuteraux tableauTous les types composite ont une syntaxe similaire pour la creacuteation des valeurs Pour les tableaux cela ressemble agrave
Tableau de 3 entiers[3]int1 2 3
Tableau de 10 entiers les trois premiers nrsquoeacutetant pas agrave zeacutero[10]int 1 2 3
Vous ne voulez pas compter Utilisez pour la initialiser la longueur[]int1 2 3
Vous ne voulez pas tous les initialiser Utilisez les paires keyvalue [10]int21 31 51 71
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 3: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/3.jpg)
Exercices
Des questions
Tableaux
Tableaux (arrays)Les tableaux en Go sont quelque peu diffeacuterents de ceux en C plus comme des tableaux en Pascal (Slices le prochain sujet se comportent un peu plus comme des tableaux C)
var ar [3]int deacuteclares ar comme eacutetant un tableau de 3 entiers initialiseacutes agrave zeacutero
La taille fait partie du type
La fonction native len renvoie la taille len(ar) == 3
Les tableaux sont des valeursLes tableaux sont des valeurs pas des pointeurs implicites comme en C Vous pouvez reacutecupeacuterer lrsquoadresse drsquoun tableau attribuer un pointeur agrave un tableau (par exemple pour le passer efficacement sans recopie agrave une fonction)
func f(a [3]int) fmtPrintln(a) func fp(a [3]int) fmtPrintln(a) func main()
var ar [3] intf(ar) passe une copie de arfp(ampar) passe un pointeur sur ar
Sortie(Print et consors reconnaissent les tableaux) [0 0 0]amp[0 0 0]
Les liteacuteraux tableauTous les types composite ont une syntaxe similaire pour la creacuteation des valeurs Pour les tableaux cela ressemble agrave
Tableau de 3 entiers[3]int1 2 3
Tableau de 10 entiers les trois premiers nrsquoeacutetant pas agrave zeacutero[10]int 1 2 3
Vous ne voulez pas compter Utilisez pour la initialiser la longueur[]int1 2 3
Vous ne voulez pas tous les initialiser Utilisez les paires keyvalue [10]int21 31 51 71
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 4: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/4.jpg)
Tableaux
Tableaux (arrays)Les tableaux en Go sont quelque peu diffeacuterents de ceux en C plus comme des tableaux en Pascal (Slices le prochain sujet se comportent un peu plus comme des tableaux C)
var ar [3]int deacuteclares ar comme eacutetant un tableau de 3 entiers initialiseacutes agrave zeacutero
La taille fait partie du type
La fonction native len renvoie la taille len(ar) == 3
Les tableaux sont des valeursLes tableaux sont des valeurs pas des pointeurs implicites comme en C Vous pouvez reacutecupeacuterer lrsquoadresse drsquoun tableau attribuer un pointeur agrave un tableau (par exemple pour le passer efficacement sans recopie agrave une fonction)
func f(a [3]int) fmtPrintln(a) func fp(a [3]int) fmtPrintln(a) func main()
var ar [3] intf(ar) passe une copie de arfp(ampar) passe un pointeur sur ar
Sortie(Print et consors reconnaissent les tableaux) [0 0 0]amp[0 0 0]
Les liteacuteraux tableauTous les types composite ont une syntaxe similaire pour la creacuteation des valeurs Pour les tableaux cela ressemble agrave
Tableau de 3 entiers[3]int1 2 3
Tableau de 10 entiers les trois premiers nrsquoeacutetant pas agrave zeacutero[10]int 1 2 3
Vous ne voulez pas compter Utilisez pour la initialiser la longueur[]int1 2 3
Vous ne voulez pas tous les initialiser Utilisez les paires keyvalue [10]int21 31 51 71
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 5: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/5.jpg)
Tableaux (arrays)Les tableaux en Go sont quelque peu diffeacuterents de ceux en C plus comme des tableaux en Pascal (Slices le prochain sujet se comportent un peu plus comme des tableaux C)
var ar [3]int deacuteclares ar comme eacutetant un tableau de 3 entiers initialiseacutes agrave zeacutero
La taille fait partie du type
La fonction native len renvoie la taille len(ar) == 3
Les tableaux sont des valeursLes tableaux sont des valeurs pas des pointeurs implicites comme en C Vous pouvez reacutecupeacuterer lrsquoadresse drsquoun tableau attribuer un pointeur agrave un tableau (par exemple pour le passer efficacement sans recopie agrave une fonction)
func f(a [3]int) fmtPrintln(a) func fp(a [3]int) fmtPrintln(a) func main()
var ar [3] intf(ar) passe une copie de arfp(ampar) passe un pointeur sur ar
Sortie(Print et consors reconnaissent les tableaux) [0 0 0]amp[0 0 0]
Les liteacuteraux tableauTous les types composite ont une syntaxe similaire pour la creacuteation des valeurs Pour les tableaux cela ressemble agrave
Tableau de 3 entiers[3]int1 2 3
Tableau de 10 entiers les trois premiers nrsquoeacutetant pas agrave zeacutero[10]int 1 2 3
Vous ne voulez pas compter Utilisez pour la initialiser la longueur[]int1 2 3
Vous ne voulez pas tous les initialiser Utilisez les paires keyvalue [10]int21 31 51 71
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 6: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/6.jpg)
Les tableaux sont des valeursLes tableaux sont des valeurs pas des pointeurs implicites comme en C Vous pouvez reacutecupeacuterer lrsquoadresse drsquoun tableau attribuer un pointeur agrave un tableau (par exemple pour le passer efficacement sans recopie agrave une fonction)
func f(a [3]int) fmtPrintln(a) func fp(a [3]int) fmtPrintln(a) func main()
var ar [3] intf(ar) passe une copie de arfp(ampar) passe un pointeur sur ar
Sortie(Print et consors reconnaissent les tableaux) [0 0 0]amp[0 0 0]
Les liteacuteraux tableauTous les types composite ont une syntaxe similaire pour la creacuteation des valeurs Pour les tableaux cela ressemble agrave
Tableau de 3 entiers[3]int1 2 3
Tableau de 10 entiers les trois premiers nrsquoeacutetant pas agrave zeacutero[10]int 1 2 3
Vous ne voulez pas compter Utilisez pour la initialiser la longueur[]int1 2 3
Vous ne voulez pas tous les initialiser Utilisez les paires keyvalue [10]int21 31 51 71
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 7: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/7.jpg)
Les liteacuteraux tableauTous les types composite ont une syntaxe similaire pour la creacuteation des valeurs Pour les tableaux cela ressemble agrave
Tableau de 3 entiers[3]int1 2 3
Tableau de 10 entiers les trois premiers nrsquoeacutetant pas agrave zeacutero[10]int 1 2 3
Vous ne voulez pas compter Utilisez pour la initialiser la longueur[]int1 2 3
Vous ne voulez pas tous les initialiser Utilisez les paires keyvalue [10]int21 31 51 71
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 8: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/8.jpg)
Pointeurs sur des liteacuteraux tableauVous pouvez reacutecupeacuterer lrsquoadresse drsquoun liteacuteral tableau afin drsquoavoir un pointeur sur une instance nouvellement creacuteeacutee
func fp(a [3]int) fmtPrintln(a) func main()
for i = 0 i lt 3 i++ fp(amp[3]inti ii iii)
Output
amp[0 0 0]amp[1 1 1]amp[2 4 8]
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 9: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/9.jpg)
Les slices
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 10: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/10.jpg)
Les slicesUne tranche (slice) est une reacutefeacuterence vers une section drsquoune tableau Les slices sont habituellement plus utiliseacutees que des tableaux pleins Une slice ne coute pas grand chose en place et performance (plus agrave venir)
Un type slice ressemble agrave un type tableau sans la taille var a []int
La fonction native len(a) retourne le nombre drsquoeacuteleacutements de la tranche
On creacutee une slice en tranchant un tableau ou une autre slice a = ar[79]
Les index valides de a seront alors 0 et 1 len(a)==2
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 11: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/11.jpg)
Raccourcis pour les slices
Quand on creacutee une slice le premier index est par deacutefaut agrave 0 ar[n] signifie ar[0n]
Le second index est par deacutefaut len(arrayslice)ar[n] signifie ar[nlen(ar)]
Enfin pour creacuteer une slice drsquoun tableau ar[] signifie ar[0len(ar)]
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 12: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/12.jpg)
Un slice reacutefeacuterence un tableau Conceptually
type Slice struct base elemType pointeur sur le 0egraveme eacuteleacutementlen int nb drsquoeacuteleacutements dans la slicecap int num drsquoeacuteleacutements disponibles
Arrayar
Slicea=ar[79]
7 1 5 4 3 8 7 2 11 5 3
base=ampar[7] len=2 cap=4
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 13: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/13.jpg)
Construire une sliceLes liteacuteraux slice ressemblent agrave des liteacuteraux tableau sans la taille
var slice = []int12345Ce qui se passe crsquoest la creacuteation drsquoun tableau de longueur 5 suivie de la creacuteation drsquoune slice qui y fait reacutefeacuterence
Nous pouvons eacutegalement allouer une slice (et le tableau sous-jacent) avec la fonction native make
var s100 = make([]int 100) slice 100 ints
Pourquoi make et pas new Parce nous avons besoin de fabriquer une slice et pas seulement drsquoallouer de la meacutemoire Notez que make([]int 10) retourne []int tandis que new([]int) retourne []int
Utilisez make pour creacuteer des slices des maps et des channels (plus tard dans le cours)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 14: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/14.jpg)
La capaciteacute drsquoune sliceUne slice fait reacutefeacuterence agrave un tableau sous-jacent ainsi il peut y avoir des eacuteleacutements agrave lrsquoexpreacutemiteacute de la slice qui sont preacutesents dans le tableau
La fonction native cap (capacity) indique jusqursquoagrave quelle taille la slicepourrait encore grossir srsquoil le fallait
Apregravesvar ar = [10]int0123456789var a = ar[57] reacutefeacuterence vers le sous-tableau56
len(a) est 2 et cap(a) est 5 On peut reslicera = a[04] reacutefeacuterence vers le sous-tableau 5678
len(a) est deacutesormais 4 mais cap(a) est toujours 5
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 15: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/15.jpg)
Retailler une sliceLes slices peuvent ecirctre utiliseacutees pour faire grossir un tableau
var sl = make([]int 0 100) len 0 cap 100
func appendToSlice(i int sl []int) []int if len(sl) == cap(sl) error() n = len(sl)sl = sl[0n+1] eacutetend drsquoune longueur de 1sl[n] = ireturn sl
Ainsi la longueur de sl est toujours le nombre drsquoeacuteleacutements mais il grossit avec le besoin Ce style est leacuteger et propre agrave Go
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 16: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/16.jpg)
Les slices sont leacutegegraveresSentez vous libres drsquoallouer et de retailler des slices comme vous lrsquoentendez Elles sont leacutegegraveres pas de besoin drsquoallocation Souvenez-vous que ce sont des reacutefeacuterences ainsi le stockage sous-jacent peut ecirctre modifieacute
Par exemple les IO utilisent des slices pas des compteursfunc Read(fd int b []byte) intvar buffer [100]bytefor i = 0 i lt 100 i++
remplit le buffer un octet agrave la foisRead(fd buffer[ii+1]) pas drsquoallocation ici
Scinder un buffer
header data = buf[n] buf[n]
Les chaicircnes de caractegraveres peuvent ecirctre sliceacutees eacutegalement avec la mecircme efficaciteacute
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 17: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/17.jpg)
Les dictionnaires (maps)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 18: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/18.jpg)
Les dictionnaires (Map)Les dictionnaires sont un autre type de reacutefeacuterence Ils sont deacuteclareacutes
de la faccedilon suivante var m map[string]float64
Ceci deacuteclare un dictionnaire indexeacute avec une clef de type string et une valeur de type float64
Crsquoest analogue agrave ce que lrsquoon trouve en C++type mapltstringfloat64gt (note the )
Etant donneacute un dictionnaire m len(m) retourne le nombre de clefs
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 19: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/19.jpg)
Creacuteation drsquoun dictionnaireComme avec une slice une variable dictionnaire ne se reacutefegravere agrave rien vous devez mettre quelque chose dedans avant de lrsquoutiliser
Trois faccedilons de le faire 1) Liteacuteral liste de clefvaleur
m = map[string]float6411 pi31415
2) Creacuteationm = make(map[string]float64) make pas new
3) Affectationvar m1 map[string]float64m1 = m m1 and m now refer to same map
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 20: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/20.jpg)
Indexation drsquoun dictionnaire(Les prochains exemples utilisent tous
m = map[string]float6411 pi31415)
Accegravede agrave un eacuteleacutement comme agrave une valeur si pas preacutesente renvoie une valeur zeacutero
one = m[1]zero = m[pas preacutesent] mets zero agrave 00
Stocke un eacuteleacutement
m[2] = 2m[2] = 3
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 21: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/21.jpg)
Test de lrsquoexistencePour tester si une clef est peacutesente dans un dictionnaire nous pouvons utiliser une affectation multiple la forme ldquovirgule ok(comma ok)rdquo
m = map[string]float6411 pi31415var value float64var present boolvalue present = m[x]
or idiomatiquement
value ok = m[x] la forme comma ok
Si x est preacutesent dans le dictionnaire positionne le booleacuteen agrave true et la valeur et reacutecupegravere la valeur associeacute agrave la clef donneacutee Si non positionne le booleacuteen agrave false et renvoie la valeur zero pour le type consideacutereacute
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 22: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/22.jpg)
SuppressionLa suppression drsquoune entreacutee se fait de la maniegravere suivante
m = map[string]float64110 pi31415var keep boolvar value float64var x string = f()m[x] = v keep
Si keep est true lrsquoaffectation de v dans le dictionnaire srsquoeffectue bien si keep est false lrsquoentreacutee du dictionnaire pour la clef x est supprimeacuteem[x] = 0 false supprime lrsquoentreacutee pour x
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 23: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/23.jpg)
For et rangeLa boucle for possegravede une syntaxe speacuteciale dans le cas drsquoune iteacuteration sur un tableau drsquoune slice ou drsquoun dictionnaire
m = map[string]float64110 pi31415for key value = range m fmtPrintf(key s value gn key value)
Srsquoil nrsquoy a qursquoune seule variable ne reacutecupegravere que la clef for key = range m fmtPrintf(key sn key)
Les variables peuvent ecirctre affecteacutees ou deacuteclareacutees en utilisant = Pour les tableaux et les slices renvoie lrsquoindex et la valeur
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 24: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/24.jpg)
Range sur une chaicircne de caractegraveresUn for utilisant un range sur une chaicircne boucle sur les points code Unicode non sur les octets (Utiliser []byte pour les octets ou utiliser le for standard) La chaicircne est consideacutereacutee devant contenir des caractegraveres en UTF-8
La boucles = [u00ffu754c]for i c = range s
fmtPrintf(dq i c) q for quoted
affiche 0[ 1yuml 31049988 6]lsquo
Si un UTF-8 est erroneacute le caractegravere est mis agrave U+FFFD et lrsquoindex avance drsquoun seul octet
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 25: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/25.jpg)
Structs
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 26: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/26.jpg)
StructsLes structures vont vous sembler familiegraveres ce sont de simples deacuteclarations de
champs var p struct x y float64
De maniegravere plus communetype Point struct x y float64
var p Point
Les structs permettent au programmeur de deacutefinir les bornes meacutemoire
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 27: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/27.jpg)
Les structs sont des valeursLes structs sont des valeurs et new(StructType) retourne un pointeur sur une valeur zeacutero (memoire tout agrave zeacutero)
type Point struct x y float64
var p Pointpx = 7py = 234var pp Point = new(Point)pp = pppx = Pi sucre syntaxique pour(pp)x
Il nrsquoexiste pas de notation -gt pour les pointeurs sur structure Go vous fournit lrsquoindirection pour vous
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 28: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/28.jpg)
Construction des structsLes structures sont des valeurs ainsi vous pouvez en faire une ldquozeacuterofieacuteerdquo juste en la deacuteclarant
var p Point zeroed valueVous pouvez aussi en allouer une avec new
pp = new(Point) allocation idiomatique
Les liteacuteraux struct ont la syntaxe attenduep = Point72 84p = Pointy84 x72pp = ampPoint72 84 idiomatiquepp = ampPoint eacutegalement idiomatique == new(Point)
Comme avec les tableaux prendre lrsquoadresse drsquoun liteacuteral struct donne lrsquoadresse drsquoune valeur nouvellement creacuteeacutee
Ces exemples sont des constructeurs
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 29: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/29.jpg)
Exportation des types et champsLes champs (et meacutethodes agrave venir) drsquoune structure doivent commencer avec une majuscule pour ecirctre visible agrave lrsquoexteacuterieur du package
Type et champs priveacutes type point struct x y float64
Typeet champs exporteacutes type Point struct X Y float64
Type exporteacute avec un mix des champstype Point struct X Y float64 exporteacutename string pas exporteacute
Vous pouvez mecircme avoir un type priveacute avec des champs exporteacutes Exercice quand est-ce utile
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 30: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/30.jpg)
Champs anonymesA lrsquointeacuterieur drsquoune structure vous pouvez deacuteclarer des champs comme une autre structure sans leur donner un nom de champ
Crsquoest ce que lrsquoon appelle des champs anonymes et ils se comportent comme si les stcuture interne eacutetait simplement inseacutereacutee ou ldquoembarqueacuteerdquo agrave lrsquoexteacuterieur
Ce meacutecanisme simple fournit une faccedilon de deacuteriver quelques uns ou la totaliteacute de votre impleacutementation drsquoun autre type ou de types
Un exemple agrave suivre pour illustrer le propos
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 31: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/31.jpg)
Un champ struct anonymetype A struct
ax ay inttype B struct
Abx by float64
B agit comme si il posseacutedait 4 champs ax ay bx et by Crsquoest presque comme si B eacutetait ax ay int bx by float64
Neacuteanmoins les liteacuteraux comme B doivent ecirctre remplis dans le deacutetail
b = BA1 2 30 40fmtPrintln(bax bay bbx bby)
Affiche 1 2 3 4
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 32: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/32.jpg)
Les champs anonymes ont le type comme nom
Mais crsquoest plus riche qursquoune simple interpolation de champs B aussi a un champ A Le champ anonyme ressemble agrave un champ dont le nom est son type
b = BA 1 2 30 40fmtPrintln(bA)
Affiche 1 2
Si A venait drsquoun autre package le champ srsquoappelerait eacutegalement Aimport pkgtype C struct pkgA c = C pkgA1 2fmtPrintln(cA) pas cpkgA
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 33: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/33.jpg)
Champs anonymes de nrsquoimporte quel type
Nrsquoimporte quel type nommeacute ou pointer sur celui-ci peut ecirctre utiliseacute dans un type anonyme et peut apparaicirctre agrave nrsquoimporte quel endroit de la structure
type C struct x float64intstring
c = C35 7 bonjourfmtPrintln(cx cint cstring)
Affiche 35 7 bonjour
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 34: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/34.jpg)
Conflits et masquageSrsquoil existe deux champs avec les mecircme noms (eacuteventuellement un nom de type deacuteriveacute) les regravegles suivantes srsquoappliquent
1) Un champ externe masque un champs interne Ceci fournit une faccedilon de surcharger un champs ou une meacutethode
2) Si le mecircme nom apparait deux fois agrave un mecircme niveau crsquoest une erreur si le nom est utiliseacute par le programme (si pas utiliseacute pas de problegraveme)
Pas de regravegles pour reacutesoudre les ambiguiumlteacutes doit ecirctre corrigeacute par le programmeur
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 35: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/35.jpg)
Exemples de conflitstype A struct a int type B struct a b int type C struct A B var c C
Utiliser ca est une erreur est-ce cAa ou cBatype D struct B b float64 var d D
Utiliser db est OK il srsquoagit de float64 et non de dBb
On peut acceacuteder agrave b via DBb
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 36: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/36.jpg)
Meacutethodes
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 37: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/37.jpg)
Meacutethodes sur les structuresGo ne possegravede pas de classes mais vous pouvez attacher des meacutethodes agrave nrsquoimporte quel type Les meacutethodes sont deacuteclareacutees de maniegravere seacutepareacutee des types comme des fonctions avec un reacutecepteur explicite
type Point struct x y float64 une meacutethode sur Pointfunc (p Point) Abs() float64 return mathSqrt(pxpx + pypy)
Note reacutecepteur explicite (pas de this automatique) dans le cas du type Point utiliseacute dans la meacutethode
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 38: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/38.jpg)
Meacutethodes sur des valeurs structUne meacutethode ne requiegravere pas un pointeur comme reacutecepteur
type Point3 struct x y z float64 une meacutethode sur Point3func (p Point3) Abs() float64 return mathSqrt(pxpx + pypy + pzpz)
Ceci est une peu cher payeacute parce que Point3 sera toujours passeacute par valeur agrave la meacutethode et non par pointeur mais crsquoest valide en Go
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 39: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/39.jpg)
Invocation drsquoune meacutethodeJuste comme vous y attendez
p = ampPoint 3 4 fmtPrint(pAbs()) affichera 5
Un exemple sans structuretype IntVector []intfunc (v IntVector) Sum() (s int)
for _ x = range v identificateur blanks += xreturn
fmtPrintln(IntVector1 2 3Sum()
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 40: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/40.jpg)
Les regravegles de base des meacutethodes Les meacutethodes sont attacheacutees agrave un type nommeacute disons Foo et y sont lieacutees statiquement
Le type drsquoun reacutecepteur dans une meacutethode peut ecirctre soit Foo ou Foo Vous pouvez avoir des meacutethodes Foo et des meacutethodes Foo Foo lui-mecircme ne peut pas ecirctre un type pointeur bien que les meacutethodes puissent avoir un reacutecepteur de type Foo
Le type Foo doit ecirctre deacutefini dans le mecircme package que celui de ses meacutethodes
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 41: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/41.jpg)
Pointeurs et valeursGo deacutereacutefeacuterence automatiquement les valeurs pour vous agrave lrsquoinvocation des meacutethodesPar exemple mecircme si une meacutethode possegravede un type reacutecepteur Point vous pouvez lrsquoinvoquer sur une valeur de type Point
p1 = Point 3 4 fmtPrint(p1Abs()) sucre syntaxique pour
(ampp1)Abs()
De maniegravere similaire si des meacutethodes sont sur Point3 vous pouvez utiliser une valeur de type Point3
p3 = ampPoint3 3 4 5 fmtPrint(p3Abs()) sucre syntaxique pour
(p3)Abs()
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 42: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/42.jpg)
Meacutethodes sur des champs anonymes
Naturellement quand un champ anonyme est embarqueacute dans une structure les meacutethodes de ce type sont embarqueacutees de la mecircme faccedilon ndash en effet il herite des meacutethodes
Ce meacutecanisme offre une faccedilon simple drsquoeacutemuler certains effets du sous-classage et de lrsquoheacuteritage
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 43: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/43.jpg)
Exemple de champ anonymetype Point struct x y float64 func (p Point) Abs() float64
type NamedPoint struct Pointname string
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 5
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 44: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/44.jpg)
Surcharger une meacutethodeLa surcharge fonctionne juste comme avec les champs
type NamedPoint struct Pointname string
func (n NamedPoint) Abs() float64
return nPointAbs() 100
n = ampNamedPointPoint3 4 PythagorasfmtPrintln(nAbs()) prints 500
Bien entendu vous pouvez avoir des champs multiples anonymes avec des types varieacutes ndash une simple version de lrsquoheacuteritage multiple Les regravegles de reacutesolution des conflits rendent les choses simples neacuteanmoins
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 45: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/45.jpg)
Un autre exempleUne utilisation encore plus irreacutesistible des champs anonymes
type Mutex struct func (m Mutex) Lock()
type Buffer struct data [100]byteMutex ne neacutecessite pas drsquoecirctre le premier dans le buffer
var buf = new(Buffer)bufLock() == bufMutexLock()
Notez que le reacutecepteur de Lock (lrsquoadresse de) est le champ Mutex pas la structure environnante (contraste avec le sou-classage et les mix-in Lips)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 46: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/46.jpg)
Drsquoautres typesLes meacutethodes ne sont pas juste pour les structures Elles peuvent ecirctre deacutefinies pour
nrsquoimporte quel type (non pointeur)Le type doit ecirctre deacutefini neacuteanmoins dans votre package Vous ne pouvez donc pas eacutecrire une meacutethode pour le type int mais vous pouvez deacuteclarer un nouveau type int et lui attribuer des meacutethodes
type Jourint
var nomsjour= []string Lundi Mardi Mercredi
func (jour Jour) String() string return nomsjour[jour]
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 47: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/47.jpg)
Drsquoautres types (suite)Now we have an enumeration-like type that knowshow to print itself
const (Lundi Jour= iotaMardiMercredi
)var jour= MardifmtPrintf(q jourString()) affiche ldquoMardi
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 48: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/48.jpg)
Print comprend les meacutethodes String
Au moyen de techniques divuldueacutees bientocirct fmtprint et ses amies peuvent identifier les valeurs qui impleacutementent la methode String comme deacutefinie pour la type Jour De telles valeurs sont automatiquement formateacutees en invoquant la meacutethode
Ainsi
fmtPrintln(0 Monday 1 Tuesday)
Affiche 0 Lundi 1 Mardi
Definissez une meacutethodes String pour vos types et ils srsquoafficheront de maniegravere sympathique sans plus de travail
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 49: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/49.jpg)
Visibiliteacute des champs et des meacutethodes
RevisionGo est tregraves diffeacuterent du C++ dans le domaine de la visibiliteacute
Les regravegles de Go sont les suivantes1 Go possegravede une visibiliteacute package(C++ a une visibiliteacute fichier)2 Lrsquoorthographe determine ce qui est exporteacute ou local (pubpriv)3 Structs dans un mecircme package ont un plein accegraves aux champs et
meacutethodes des autres types4 Un type local peut exporter ses champs et meacutethodes5 Pas de vrai sous-classage ni notion de ldquoproteacutegeacuterdquo6 Ces simples regravegles fonctionnent trsegrave bien en pratique pas de sur-
specification deacuteconnecteacutee du reacuteel
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 50: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/50.jpg)
Interfaces
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 51: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/51.jpg)
Regardez avec attention
Nous allons jeter un coup drsquooeil sur lrsquoaspect le plus inhabituel de Go
Les interfaces
Laissez vos preacutejugeacutes svp sous le paillasson
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 52: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/52.jpg)
Introduction
Jusqursquoagrave preacutesent tous les types que nous avons examineacutes eacutetaient concrets ils impleacutementaient quelque chose
Il y a un type suppleacutementaire agrave consideacuterer encore lrsquointerface Crsquoest compleacutetement abstrait Il nrsquoimpleacutemente RIEN Ill speacutecifie agrave laplace un ensemble de proprieacuteteacutes qursquoune imeacuteplmentation doit fournir comme en java en quelque sorte
Mais par rapport agrave java le concept de laquo la valeur interface raquo en Go est tout agrave fait nouveau
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 53: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/53.jpg)
Deacutefinition drsquoune interfaceLe mot interface est un peu surchargeacute en Go il y a le concepte drsquoune interface et il y a un type interface et ensuite il y a des valeurs de ce type Premiegraverement le concept
DeacutefinitionUne interface est un ensemble de meacutethodes
Pour tourner autour les meacutethodes impleacutementeacutees par un type concret comme une structure forment lrsquointerface de ce type
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 54: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/54.jpg)
ExampleNous avons vu ce type simple auparavant
type Point struct x y float64 func (p Point) Abs() float64
Lrsquointerface du type Point possegravede la meacutethode Abs() float64
Ce nrsquoest pas func (p Point) Abs() float64
Parce que lrsquointerface fait abstraction du reacutecepteur
Nous embarquons Point dans un nouveau type NamedPointNamedPoint possegravede la mecircme interface
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 55: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/55.jpg)
Le type interfaceUn type interface est une spcification drsquoune interface un ensemble de meacutethodes impleacutementeacutees par drsquoautres typesCi-dessous une interface simple avec une seule meacutethode
type AbsInterface interface Abs() float64 le recepteur est implicite
Ceci est la deacutefinition de lrsquointerface impleacutementeacutee par Point ou dans notre terminologiePoint impleacutemente AbsInterface
eacutegalementNamedPoint et Point3 implementent AbsInterface
Les meacutethodes sont eacutecrites agrave lrsquointeacuterieur de la deacuteclaration de lrsquointerface
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 56: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/56.jpg)
Un Exempletype MonFloat float64
func (f MonFloat) Abs() float64 if f lt 0 return float64(-f) return f
MonFloat implemente AbsInterface mecircm si float64 ne le fait pas
(NB MonFloat nrsquoets pas le boxing defloat64 sa repreacutesentation est identique agrave float64)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 57: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/57.jpg)
Plusieurs vers plusieursUne interface peut ecirctre impleacutementeacutee par un nombre arbitraire de types AbsInterface est impleacutementeacute par nrsquoimporte quel qui possegravede une meacutethode avec une signature Abs() float64 nonobstant le fait que le type puisse avoir drsquoautres meacutethodes
Un type peut impleacutementer un nombre arbitraire drsquointerfaces Point en impleacutemente ainsi au moins deux
type AbsInterface interface Abs() float64 type EmptyInterface interface
Tout type impleacutemente une interface vide EmptyInterface Ce qui va nous ecirctre pratique dans le futurhellip
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 58: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/58.jpg)
Valeur interfaceUne fois qursquoune variable est deacuteclareacutee avec un type interface elle peut enregistrer nrsquoimporte quelle valeur qui impleacutement cette interface
var ai AbsInterface
pp = new(Point)ai = pp OK Point possegravede Abs()ai = 7 erreur agrave la compilation
float64 ne possegravede pas Abs()ai = MonFlottant(-7) OK MonFlottant possegravede Abs()
ai = ampPoint 3 4 fmtPrintf(aiAbs()) appel de meacutethode
affiche 5
NB ai nrsquoest pas un pointeur Crsquoest une valeur interface
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 59: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/59.jpg)
En meacutemoireai nrsquoest pas un pointeur Crsquoest une structure de
donneacutees multi-motsai A diffeacuterents instant ai possegravede un type et une valeur
diffeacuterente ai = ampPoint34 (un Point agrave lrsquoadresse 0xff1234)
ai = MyFloat(-7)
Valeur reacuteceptrice Pointeur sur une table de meacutethodes
0xff1234
-7
(Point) Abs() float64
hellip
(MyFloat) Abs() float64
hellip
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 60: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/60.jpg)
Trois choses importantes1) Les interfaces deacutefinissent un semble de meacutethodes Elles sont pures et
abstraites pas drsquoimpleacutementation pas de champs de donneacutees Go possegravede une claire seacuteparation entre interface et imeacuteplementation
2) Les valeurs interface sont juste ceci des valeurs Elles contiennent nrsquoimporte quelles valeurs concrecirctes qui imeacutepleacutementent toutes les meacutethodes deacutefinies dans lrsquointerface Cette valeur concrecircte peut ou pas ecirctre un pointeur
3) Les types impleacutementent les interface sen ayant juste ses meacutethodes Eils ne doivent pas deacuteclarer ce qursquoelles font Par exemple tout type impleacutemente une interface vide interface
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 61: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/61.jpg)
Exemple ioWriterCi-apregraves la signature concrecircte de of fmtFprintf
func Fprintf(w ioWriter f string a interface)(n int error osError)
Elle nrsquoeacutecrit pas dans un fichier mais eacutecrit vers quelque chose du type ioWriter qui est deacutefini dans le package io
type Writer interface Write(p []byte) (n int err osError)
Fprintf peut par conseacutequent ecirctre utiliseacute pour eacutecrire sur nrsquoimporte quel type qui possegravede une meacutethode Write Write ce qui inclue les fichiers les pipes les connexions reacuteseau etchellip
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 62: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/62.jpg)
IO bufferiseacutees Un buffer en eacutecriture vant du package bufio
type Writer struct
bufioWriter impleacutemente la meacutethode canonique Writefunc (b Writer) Write(p []byte) (n int err osError)
Crsquoest aussi une ldquofactoryrdquo donnez lui un ioWriter et il retrounera un ioWriter bufferiseacute de la forme drsquoun bufioWriterfunc NewWriter(wr ioWriter) (b Writer err osError)
Et bien entendu osFile impleacutemente Writer eacutegalement
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 63: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/63.jpg)
Mettons tout ensembleimport (
bufio fmt os)func main()
non bufferiseacutefmtFprintf(osStdout s bonjour) bufferiseacute osStdout impleacutemente ioWriterbuf = bufioNewWriter(osStdout) fmtFprintf(buf sn monde)bufFlush()
La bufferisation fonctionne avec nrsquoimporte quoi qui WritesRessemble presque au pipes Unis nrsquoest-ce pas La composabiliteacute est tregraves puissante voir le package crypto
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 64: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/64.jpg)
Autres interface publiques dans ioLe package io possegravede
ReaderWriterReadWriterReadWriteCloser
Ce sont des interfaces styleacutees mais eacutevidentes elles capturent les fonctionnaliteacutes de nrsquoimporte quoi impleacutementant les fonctions listeacutees dans leurs noms
Crsquoest pourquoi nous pouvons avoir un package drsquoio bufferiseacutees avec une implementation seacutepareacutee des io elle-mecircmes si les deux acceptent et fournissent des valeurs interfaces
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 65: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/65.jpg)
ComparaisonEn termes C++ un tyep interface est comme une classe abstraite pure speacutecifiant les meacutethodes mais impleacutementant aucune drsquoelles
En termes java une interface ressemble plus agrave une interface Java
Mais en Go il y a une diffeacuterence majeure un type nrsquoa pas besoin de deacuteclarer lrsquointerface qursquoil impleacutemente ni besoin drsquoen heacuteriter Si le type possegravede les meacutethodes crsquoest qursquoil impleacutemente lrsquointerface
Drsquoautres diffeacuterences apparaicirctront plus clairement plus tard
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 66: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/66.jpg)
Les champs anonymes marchent aussi
type LockedBufferedWriter struct Mutex has Lock and Unlock methodsbufioWriter has Write method
func (l LockedBufferedWriter) Write(p []byte)(nn int err osError) lLock()defer lUnlock()return lWriterWrite(p) inner Write()
LockedBufferedWriter impleacutemente ioWriter mais aussi agrave travers le Mutex anonyme
type Locker interface Lock() Unlock()
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 67: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/67.jpg)
Exemple service HTTPtype Handler interface
ServeHTTP(ResponseWriter Request)
Ceci est lrsquointerface deacutefinie par le package serveur HTTP Pour deacuteclarer un serveur HTTP il faut deacutefinir un type qui impleacutemente cette iterface et se connecter au serveur (deacutetails omis)
type Counter struct n int on pourrait juste dire type Counter int
func (ctr Counter) ServeHTTP(w httpResponseWriter
req httpRequest) fmtFprintf(w counter = dn ctrn)
ctrn++
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 68: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/68.jpg)
Une fonction (type) qui est impleacutemente un serveur HTTP
func notFound(w httpResponseWriter req httpRequest)wSetHeader(Content-Type textplain +charset=utf-8)wWriteHeader(StatusNotFound)wWriteString(404 page not foundn)
Maintenant deacutefinissons un type qui impleacutemente ServeHTTP
type HandlerFunc func(httpResponseWriter httpRequest)func (f HandlerFunc) ServeHTTP(w httpResponseWriterreq httpRequest)
f(w req) the receivers a func call it
var Handle404 = HandlerFunc(notFound)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 69: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/69.jpg)
Containers et interface videAperccedilu de la mise en œuvre des vecteurs (en pratique on tend agrave utiliser des slices
brutes agrave la place mais crsquoest informatif)
type Element interface
Vector est le container lui-mecircmetype Vector []Element
At() retourne le ilsquoegraveme eacuteleacutementfunc (p Vector) At(i int) Element
return p[i]
Les Vectors peuvent contenir nrsquoimporte quoi parce tout type impleacutemente lrsquointerfac vide
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 70: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/70.jpg)
AssertionsUne fois que vous avez mis quelque chose dans Vector il est stockeacute comme une valeur interface On a besoin de lrsquoldquounboxerrdquo pour reacutecupeacuterer lrsquoeacuteleacutement original utilise pour cela une assertion Syntaxe
interfaceValue(typeToExtract)
Echouera si le type est mauvais ndash mais nous verrons cela dans le prochain slidevar v vectorVectorvSet(0 1234) stockeacute comme une valeur interface i = vAt(0) reacutecupeacutereacute comme interfaceif i = 1234 erreur agrave la compilationif i(float64) = 1234 OKif i(int) = 1234 erreur agrave lrsquoexeacutecutionif i(MyFloat) = 1234 err pas MyFloat
Les assertions ne sont leveacutees qursquoagrave lrsquoexecution Le compilateur rejette les assertions qui sont sucircres drsquoeacutechouer
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 71: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/71.jpg)
Conversion drsquointerface vers une autre interface
Jusqursquoagrave preacutesent nous deacuteplaceacute des valeurs reacuteguliegraveres de ou vers des valeurs interface mais les valeurs interface qui contiennent les meacutethodes approprieacutees peuvent aussi ecirctre converties
En effet crsquoest le mecircme scheacutema que unboxer une valeur interface pour extraire la valeur concrecircte sous-jacente puis de la reboxer pour avoir un nouveau tyecirc interface Le succegraves de la conversion deacutepend de la valeur sous-jacente pas du type drsquointerface originel
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 72: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/72.jpg)
Exemple de conversion interface vers interface
soitvar ai AbsInterfacetype SqrInterface interface Sqr() float64 var si SqrInterfacepp = new(Point) say Point has Abs Sqrvar empty interface
Elles sont toutes OK empty = pp tout satisfait videai = empty(AbsInterface) valeur sous-jacente
impleacutemente Abs() (eacutechec drsquoexcution sinon)
si = ai(SqrInterface) Point possegravede Sqr() mecircme si AbsInterface non
empty = si Point impleacutemente un ensemble vide Note statiquement veacuterifiable ainsi lrsquoassertion nrsquoest pas neacutecessaire
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 73: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/73.jpg)
Tester avec des assertions
On peut utiliser les assertions comma ok pour tester une valeur de type
elem = vectorAt(0)if i ok = elem(int) ok fmtPrintf(int dn i)
else if f ok = elem(float64) ok fmtPrintf(float64 gn f)
else fmtPrint(type inconnun)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 74: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/74.jpg)
Tester avec un type switch
Special syntax
switch v = elem(type) liteacuteral keyword typecase intfmtPrintf(est int dn v)case float64fmtPrintf( est float64 gn v)defaultfmtPrint( type inconnun)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 75: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/75.jpg)
Est-ce que v impleacutemente m()
Pour aller un peu plus loin testons si une valeur impleacutemente une meacutethode
type Stringer interface String() string if sv ok = v(Stringer) ok fmtPrintf(impleacutemente String() snsvString()) note sv pas v
Crsquoest ainsi que Print etc eacutevrifie is un type peut ecirctre afficheacute ou pas
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 76: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/76.jpg)
Reacuteflexion et hellipIl existe un package (reflect) qui vous permet drsquoexaminer des valeurs pour deacutecouvrir leur type Trop intriqueacute pour ecirctre deacutecrite ici
mais Printf etc lrsquoutilise pour analyser ses arguments
func Printf(format string args interface)(n int err osError)
A lrsquointeacuterieur de Printf les args deviennent une slice du type speacutecifieacute ie []interface et Printf utilise le package reacuteflexion pour deacutepaqueter chaque eacuteleacutement pour analyser son type
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 77: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/77.jpg)
Reacuteflexion et PrintCommeacute reacutesultat Printf et consors connaissent les types reacuteels des leurs arguments Parce ils connaissent si els arguments sont non signeacutes ou longs il nrsquoy a pas de u ou ld seulementd
Crsquoest ainsi que Print et Println peuvent afficher les arguments proprement sans une chaine de formatage
Il ya aussi un format v (value) qui donne une sortie agreacuteable par deacutefaut that gives default pour nrsquoimporte quelles valeurs de nrsquoimporte quel type pour Printf
fmtPrintf(v v v v -1 rdquobonjour[]int123 uint64(456))
Affiche -1 bonjour [1 2 3] 456
En fait v est identique au formatage effectueacutee par Print et Println
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 78: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/78.jpg)
Fonctions laquo variadiques raquo
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 79: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/79.jpg)
Fonctions laquo variadiques raquo hellipLes listes de paramegravetres agrave longueur variable sont deacuteclareacutees avec la syntaxe suivante T ougrave T est le type des arguments individuels De tels arguments doivent ecirctre le dernier de la liste drsquoarguments A lrsquointeacuterieur drsquoune fonction lrsquoargument variadique possegravede implictement le type []T
func Min(args int) int min = int(^uint(0)gtgt1) int le plus large possiblefor _ x = range args args possegravede le type[]intif min gt x min = x return min
fmtPrintln(Min(123) Min(-27) Min() Min(782))
affiche1 -27 2147483647 2
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 80: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/80.jpg)
Slices dans les variadiquesLrsquoargument devient une slice Qursquoarrive t il si vous voulez passer la slice comme argument directement Utilisez Lors de lrsquoappel (fonctionne seulement avec les variadiques)
Se rappeler que func Min(args int) int
Les deux invocations retournent -2Min(1 -2 3)slice = []int1 -2 3Min(slice) Transforme une slice en arguments
Ceci est une erreur de type Min(slice)
Parce que la slice ets de type []int tandis que les arguments Min doivent ecirctre individuellement int Le est obligatoire
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 81: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/81.jpg)
Printf en erreurNous pouvons utiliser le truc pour entourer Printf ou une de ses variantes pour creacuteer un handler drsquoerreur personnaliseacute
func Errorf(fmt string args interface) fmtFprintf(osStderr MyPkg +fmt+n args)osExit(1)
Nous pouvons lrsquoutiliser ainsi
if err = osChmod(file 0644) err = nil Errorf(couldnt chmod q s file err)
Sortie (qui inclut un retour charriot)
MyPkg couldnt chmod foobar permission denied
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 82: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/82.jpg)
AppendLa fonction native append qui ets utiliseacutee pour faire grossir une slice est
variadique Elle possegravede en effet cette signature
append(s []T x T) []T
Ougrave une slice et T est son type eacutelement Il retourne une slice avec lrsquoeacuteleacutement x ajouteacute agrave s
slice = []int1 2 3slice = append(slice 4 5 6)fmtPrintln(slice)
affiche[1 2 3 4 5 6]
Si possible append fair grossir la slice en taille
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 83: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/83.jpg)
Ajouter une slice
Si vous deacutesirez ajouter une slice complegravete plutocirct que des eacutelements individuels nous utilisons de nouveau hellip lors de lrsquoappel
slice = []int1 2 3slice2 = []int4 5 6slice = append(slice slice2) hellip est neacutecessairefmtPrintln(slice)
Cet exemple aussi affiche[1 2 3 4 5 6]
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 84: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/84.jpg)
Exercices
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 85: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/85.jpg)
Exercice jour 2
Regarder le package http
Ecrire un serveur HTTP qui preacutesnete des pages dans un systegraveme de fichier mais passablement transformeacute peut-ecirctre rot13 peut-ecirctre quelque chose drsquoun peut plus imaginatif Pouvez-vous rendre la trasnformation substituable Pouvez-vous travailler avec votre programme de suite Fibonacci
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-
![Page 86: Le langage Go 2ème partie](https://reader036.vdocuments.us/reader036/viewer/2022070422/56816597550346895dd86ccb/html5/thumbnails/86.jpg)
Prochaine leccedilon
bull Concurrence et communication
- Le langage Go 2egraveme partie
- Sommaire de la journeacutee
- Exercices
- Tableaux
- Tableaux (arrays)
- Les tableaux sont des valeurs
- Les liteacuteraux tableau
- Pointeurs sur des liteacuteraux tableau
- Les slices
- Les slices (2)
- Raccourcis pour les slices
- Un slice reacutefeacuterence un tableau
- Construire une slice
- La capaciteacute drsquoune slice
- Retailler une slice
- Les slices sont leacutegegraveres
- Les dictionnaires (maps)
- Les dictionnaires (Map)
- Creacuteation drsquoun dictionnaire
- Indexation drsquoun dictionnaire
- Test de lrsquoexistence
- Suppression
- For et range
- Range sur une chaicircne de caractegraveres
- Structs
- Structs (2)
- Les structs sont des valeurs
- Construction des structs
- Exportation des types et champs
- Champs anonymes
- Un champ struct anonyme
- Les champs anonymes ont le type comme nom
- Champs anonymes de nrsquoimporte quel type
- Conflits et masquage
- Exemples de conflits
- Meacutethodes
- Meacutethodes sur les structures
- Meacutethodes sur des valeurs struct
- Invocation drsquoune meacutethode
- Les regravegles de base des meacutethodes
- Pointeurs et valeurs
- Meacutethodes sur des champs anonymes
- Exemple de champ anonyme
- Surcharger une meacutethode
- Un autre exemple
- Drsquoautres types
- Drsquoautres types (suite)
- Print comprend les meacutethodes String
- Visibiliteacute des champs et des meacutethodes
- Interfaces
- Regardez avec attention
- Introduction
- Deacutefinition drsquoune interface
- Example
- Le type interface
- Un Exemple
- Plusieurs vers plusieurs
- Valeur interface
- En meacutemoire
- Trois choses importantes
- Exemple ioWriter
- IO bufferiseacutees
- Mettons tout ensemble
- Autres interface publiques dans io
- Comparaison
- Les champs anonymes marchent aussi
- Exemple service HTTP
- Une fonction (type) qui est impleacutemente un serveur HTTP
- Containers et interface vide
- Assertions
- Conversion drsquointerface vers une autre interface
- Exemple de conversion interface vers interface
- Tester avec des assertions
- Tester avec un type switch
- Est-ce que v impleacutemente m()
- Reacuteflexion et hellip
- Reacuteflexion et Print
- Fonctions laquo variadiques raquo
- Fonctions laquo variadiques raquo hellip
- Slices dans les variadiques
- Printf en erreur
- Append
- Ajouter une slice
- Exercices (2)
- Exercice jour 2
- Prochaine leccedilon
-