Les fonctions dans le langage de programmation Go

Ce chapitre vous explique les fonctions en GoLang, On apprendra aussi à déclarer et utiliser les différents types de fonctions dans le langage programmation GO.

Explication

Les fonctions vont nous permettre de structurer nos programmes en un groupe d'instructions qui effectueront un ensemble de tâches.

Elles permettent de simplifier notre code et de le rendre beaucoup plus lisible que ce soit pour nous ou pour les autres, mais surtout (rappelez vous que vous êtes un bon flemmard 😎) elles nous permettrons de ne pas retaper le même code plusieurs fois d’affiler.

Information

La bibliothèque standard Go fournit de nombreuses fonctions intégrées que votre programme peut appeler comme par exemple la fonction Println() de la bibliothèque fmt.

Déclarer une fonction

Pour déclarer une fonction il nous faut :

  • Le nom de la fonction (non obligatoire si votre fonction est anonyme, on verra les fonctions anonymes à la fin de ce chapitre) : C'est le nom qui décrit votre fonction, il faut juste penser à respecter les mêmes règles que pour les variables (pas d'accents, pas d'espaces, etc.). GoLang vous recommande de nommée vos fonctions en Camel case, c'est à dire que chaque mot commence par une majuscule à l’exception du premier.
  • Le type de retour de la fonction (non obligatoire si votre fonction ne retourne rien) : comme les variables les fonctions ont un type, plus précisément c'est le type de la valeur qu'elle retourne.
  • Des paramètres (non obligatoire) : Ce sont des variables que la fonction va exploiter dans son bloc de code.
func nomDeLaFonction( liste_de_paramètres ) type_de_retour
{
    /* votre code */
}

Avertissement

Une fonction non anonyme doit être déclarée en dehors de la fonction main()

Fonction sans type de retour et sans paramètres

Voici comment on déclare une fonction sans type de retour et sans aucun paramètre.

package main

import (
    "fmt"
)

// déclaration de la fonction affichage()
func affichage() {
    fmt.Println("#################################")
    fmt.Println("\tBonjour")
    fmt.Println("#################################")
}

func main() {
    affichage() // appel de la fonction affichage()
}

Résultat :

#################################
        Bonjour
#################################

Fonction sans type de retour mais avec des paramètres

Une fonction est capable de prendre autant de paramètres que vous voulez et peu importe leurs types.

package main

import (
    "fmt"
)

// prend en paramètre un type string et un int
func affichage(nom string, age int) {
    fmt.Println("Bonjour", nom, "vous avez", age, "ans")
}

func main() {
    affichage("Hatim", 9)
    affichage("Alex", 12)
}

Résultat :

Bonjour Hatim vous avez 9 ans
Bonjour Alex vous avez 12 ans

Fonction avec un type de retour

On utilisera le mot-clé return pour renvoyer une valeur depuis notre fonction. Vous pouvez ensuite stocker la valeur retournée par votre fonction dans une variable.

package main

import "fmt"

// Fonction qui retourne un type int
func maxNbr(a int, b int) int {
    if a > b {
        return a // retourne le variable a de type int
    }
    return b // retourne le variable b de type int
}
func main() {
    max := maxNbr(10, 30) // stockage du retour de la fonction dans une variable
    fmt.Println(max)

    // Utilisation directe du retour de la fonction sans la stocker dans une variable
    fmt.Printf("Valeur : %d , Type : %T\n", maxNbr(50, 30), maxNbr(50, 30)) 
}

Résultat :

30
Valeur : 50 , Type : int

Je veux plus de valeurs !

Sur l'exemple précédant notre fonction ne retournait qu'un seul type de retour, dès fois nous aurons besoin de retourner plus de valeurs. GoLang nous propose cette fonctionnalité pour renvoyer autant de valeurs souhaitées.

package main

import (
    "fmt"
)

func main() {
    a := 5
    b := 8
    fmt.Println("Avant fonction a =", a, " b =", b)
    a, b = additionTrois(a, b) // stockage du retour de la fonction dans deux variables
    fmt.Println("Après fonction a =", a, " b =", b)
}

// retourne deux types int
func additionTrois(a int, b int) (int, int) {
    return a + 3, b + 3
}

Résultat :

Avant fonction a = 5  b = 8
Après fonction a = 8  b = 11

Je veux plus de paramètres !

Il est possible en Go de déclarer une fonction qui peut prendre en compte des paramètres infinis aussi appelés paramètres variadiques .

Pour ce faire il faut rajouter des trois points ... collés avant le type du paramètre.

Exemple :

package main

import (
    "fmt"
)

func main() {
    fmt.Println(addition(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13))
}

// déclaration d'une fonction avec des paramètres infinis
func addition(param ...int) int {
    total := 0
    for _, value := range param { //j'ai mis un underscore "_" car je ne souhaite pas récupérer l'index de la range
        total += value
    }
    return total
}

Résultat :

91

Une fonction anonyme

Les fonctions anonymes sont utilisées lorsque nous voulons définir une fonction sans lui attribuer de nom , elles peuvent être déclarées et appelées directement depuis n'importe bloc de votre code enfin elles peuvent aussi être utilisées en tant que paramètres.

Je vais dans cet exemple déclarer et utiliser une fonction anonyme en tant que paramètre.

package main

import (
    "fmt"
    "math"
)

// Déclaration d'une fonction qui prend en paramètres un float64 et une fonction anonyme
func rajouterDix(a float64, fAnonyme func(float64) float64) /**/ {
    operation := fAnonyme(a) // Appel à notre fonction anonyme
    result := operation + 10
    fmt.Println(result)
}

func main() {
    // stockage de notre fonction anonyme dans une variable
    racineCarree := func(x float64) float64 { return math.Sqrt(x) }
    rajouterDix(9, racineCarree)

    /* 
        il est possible aussi d'utiliser directement une fonction anonyme 
        dans une variable sans forcement la stocker dans une variable
    */
    rajouterDix(5, func(x float64) float64 { return math.Pow(x, 2) })
}

Résultat :

13
35

Espace commentaire

Écrire un commentaire

Rejoignez la discussion

Vous devez être connecté pour poster un message.

27 commentaires

func rajouterDix(a float64, fAnonyme func(float64) float64) /**/ {    operation := fAnonyme(a) // Appel à notre fonction anonyme    result := operation + 10    fmt.Println(result)}il ya un pettit error dans l'operation d  'addition o ne peux pas fair l'addition de deux variable de deferente type

04/04/2019 à 19:33
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

@karanganwa merci pour ton message. Content de rendre service 😁

01/04/2019 à 21:32
karanganwa
Membre
Avatar de karanganwa
karanganwa
Membre

Bonjour je suis très chanceux de tomber sur ton cours bien detaillé. Merci Beaucoup

30/03/2019 à 16:08
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Pas de souci. Garde juste en tête que le ...int doit toujours être le dernier paramètre de ta liste.

30/03/2019 à 04:03
guy-delorme
Membre Actif
Avatar de guy-delorme
guy-delorme
Membre Actif

Merci, c'est beaucoup plus clair pour les paramètres infinis, je galérais avec les slices.

29/03/2019 à 21:29
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Oui, c'est là que les fonctions anonymes prennent tout leur sens. Tu peux définir une logique locale sans polluer l'espace global.

29/03/2019 à 15:49
hardy-timothee
Membre Actif
Avatar de hardy-timothee
hardy-timothee
Membre Actif

Est-ce que je peux déclarer une fonction à l'intérieur d'une autre fonction ?

29/03/2019 à 11:37
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est pour afficher le type de la valeur. Pratique pour debugger quand tu doutes du retour d'une fonction.

29/03/2019 à 04:59
couturier-lucy
Membre Actif
Avatar de couturier-lucy
couturier-lucy
Membre Actif

Pourquoi on utilise fmt.Printf avec %T dans l'exemple ?

29/03/2019 à 00:35
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

@pdevezeaud Merci !

28/03/2019 à 23:58
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Vérifie la signature de ta fonction anonyme. Elle doit correspondre exactement au type attendu par rajouterDix. Si t'as pas le même nombre de paramètres ou de retours, ça ne passera jamais.

28/03/2019 à 17:10
barbe-catherine
Membre Actif
Avatar de barbe-catherine
barbe-catherine
Membre Actif

J'ai une erreur cannot use func(...) as type func(float64) float64. Je comprends pas pourquoi.

28/03/2019 à 10:56
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est une convention forte. Si tu veux que ta fonction soit exportée (utilisable hors du package), elle doit commencer par une majuscule.

28/03/2019 à 03:03
noel-faivre
Membre Actif
Avatar de noel-faivre
noel-faivre
Membre Actif

Le Camel case est obligatoire ou c'est juste une recommandation ?

27/03/2019 à 20:01
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Carrément. Ajoute juste () à la fin de la déclaration. C'est pratique pour des exécutions immédiates.

func() { fmt.Println("coucou") }()
27/03/2019 à 12:11
vmoulin
Membre Actif
Avatar de vmoulin
vmoulin
Membre Actif

Pour les fonctions anonymes, on peut les appeler directement sans variable ?

27/03/2019 à 07:09
pdevezeaud
Membre
Avatar de pdevezeaud
pdevezeaud
Membre

Salut, l'explication sur les fonctions est très bien expliqué, tous comme les autes modules jusqu'à présent. Merci pour le partage en tous cas.

27/03/2019 à 00:30
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Aucune limitation. Tu dois juste adapter la signature : func maFonction() (string, string). Vérifie tes types, c'est tout.

26/03/2019 à 23:41
veronique-ledoux
Membre Actif
Avatar de veronique-ledoux
veronique-ledoux
Membre Actif

J'essaie de retourner deux strings au lieu de deux int, mais le compilateur râle. Une limitation ?

26/03/2019 à 18:39
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est l'identifiant vide. En Go, si tu déclares une variable que tu n'utilises pas, le compilo te bloque. Comme je veux pas l'index, je mets _ pour dire au compilo de l'ignorer.

26/03/2019 à 10:40
marcel93
Membre Actif
Avatar de marcel93
marcel93
Membre Actif

C'est quoi l'intérêt du _ dans la boucle range pour le total ?

26/03/2019 à 02:44
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

T'as sûrement oublié de préciser le type de retour dans ta signature de fonction. Si ta fonction renvoie un float64, tu dois l'écrire explicitement après les parenthèses.

25/03/2019 à 22:35
boutin-gregoire
Membre Actif
Avatar de boutin-gregoire
boutin-gregoire
Membre Actif

J'ai une erreur bizarre avec rajouterDix, ça me dit que le type de retour est manquant dans la signature.

25/03/2019 à 18:05
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Oui, utilise l'opérateur ... lors de l'appel de la fonction pour déplier ton slice. Exemple :

nums := []int{1, 2, 3}
fmt.Println(addition(nums...))
25/03/2019 à 10:20
patrick81
Membre Actif
Avatar de patrick81
patrick81
Membre Actif

Ok, ça marche mieux. Par contre, pour les fonctions variadiques avec ...int, c'est possible de passer un slice directement ?

25/03/2019 à 02:27

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire