Renvoyer plus d'une valeur
Listez les types des résultats entre parenthèses. Renvoyez les valeurs séparées par des virgules, et recevez-les de la même façon.
Les fonctions intégrées min et max existent depuis Go 1.21. L'appelant doit recevoir tous les résultats : x := minMax(nums) ne compile pas et donne assignment mismatch: 1 variable but minMax returns 2 values.
La convention (value, error)
La raison la plus courante de renvoyer deux valeurs est de signaler un échec. Par convention, l'erreur vient en dernier, et quand elle n'est pas nil, les autres résultats doivent être considérés comme sans signification.
Sortie :
port: 8080
error: port "http": strconv.Atoi: parsing "http": invalid syntax
error: port out of range
En cas d'échec, renvoyez la valeur zéro pour tous les autres résultats (0, "", nil). Le motif complet, avec l'enveloppement et la vérification, est sur la page gestion des erreurs.
L'idiome comma-ok
Plusieurs opérations intégrées renvoient un second bool facultatif qui indique si la première valeur est réelle. La variable s'appelle par convention ok.
Ces trois formes (recherche dans une map, assertion de type, réception sur un channel) sont spéciales : elles renvoient une ou deux valeurs selon le nombre de variables auxquelles vous affectez. Vos propres fonctions ne le peuvent pas. Une fonction déclarée avec deux résultats en renvoie toujours deux.
L'identifiant blanc
_ reçoit une valeur et la jette. Utilisez-le pour les résultats dont vous n'avez pas besoin :
_, err := fmt.Sscan(input, &n)
key, _ := parseLine(line)
Ignorer une erreur avec _ compile, donc ne le faites que si vous savez que l'appel ne peut pas échouer ou que l'échec n'a pas d'importance. strings.Builder.WriteString renvoie toujours une erreur nil, par exemple ; la fermeture d'un fichier après écriture, non.
Résultats nommés
Les paramètres de résultat peuvent avoir des noms. Ils sont déclarés au début de la fonction, initialisés à leur valeur zéro, et un return sans valeurs renvoie ce qu'ils contiennent.
Les noms apparaissent dans la sortie de go doc, ce qui aide quand deux résultats partagent un type : (quotient, remainder int) en dit plus que (int, int).
Un return nu dans une longue fonction est difficile à lire, parce que le lecteur doit remonter pour voir ce que contiennent les résultats. Le conseil habituel : nommez les résultats quand les noms documentent quelque chose, et écrivez quand même return quotient, remainder explicitement, sauf si la fonction fait quelques lignes.
Résultats nommés et defer
Une fonction différée s'exécute après que l'instruction return a défini les résultats et avant que l'appelant ne les reçoive. Avec des résultats nommés, la fonction différée peut les lire et les modifier. C'est ainsi qu'on ajoute du contexte à toute erreur renvoyée par une fonction, ou qu'on transforme un panic en erreur.
Ce code affiche load : empty name puis <nil>. return errors.New(...) affecte d'abord err, puis la fonction différée l'enveloppe. Plus de détails dans defer.
Masquer un résultat nommé
Les résultats nommés vivent dans la portée la plus externe de la fonction. Un := dans un bloc imbriqué crée une nouvelle variable du même nom, et un return nu renvoie alors la variable externe.
func find() (n int, err error) {
if true {
n, err := compute() // new n and err, shadowing the results
_ = n
_ = err
}
return // returns 0, nil
}
Le compilateur détecte le pire cas : un return nu dans le bloc où un résultat est masqué échoue avec result parameter err not in scope at return. Il ne détecte pas la version ci-dessus, où le return se trouve hors du bloc. Utilisez = au lieu de := quand vous visez les variables de résultat.
Erreurs courantes
- Utiliser la valeur quand err n'est pas nil. Vérifiez d'abord
err. Une fonction a le droit de renvoyer n'importe quoi avec une erreur. - Renvoyer un pointeur nil typé comme erreur.
var e *MyErr; return erenvoie uneerrornon nil. Renvoyez unnillittéral en cas de succès. - Trop de résultats. Trois résultats ou plus de sens différents sont difficiles à utiliser. Renvoyez plutôt une struct.
Questions fréquentes
Comment renvoyer plusieurs valeurs depuis une fonction en Go ?
Listez les types des résultats entre parenthèses et renvoyez les valeurs séparées par des virgules : func minMax(xs []int) (int, int) { ...; return lo, hi }. L'appelant les affecte toutes en une fois : lo, hi := minMax(nums).
Comment ignorer l'une des valeurs de retour en Go ?
Affectez-la à l'identifiant blanc _ : _, err := strconv.Atoi(s) ou n, _ := strconv.Atoi(s). Vous ne pouvez pas omettre complètement une valeur : le nombre de variables à gauche doit correspondre au nombre de résultats.
Que sont les valeurs de retour nommées en Go ?
Des paramètres de résultat qui ont un nom, comme func split(n int) (half, rest int). Ils démarrent à leur valeur zéro, peuvent être affectés dans le corps, et un return nu renvoie leurs valeurs actuelles. Ils permettent aussi à une fonction différée de modifier ce que reçoit l'appelant.
Faut-il utiliser les retours nus en Go ?
Seulement dans les fonctions courtes. Un return nu dans une longue fonction masque ce qui est renvoyé et facilite les bugs de masquage. Les guides de style Go recommandent de nommer les résultats pour la documentation et de renvoyer des valeurs explicites dans tout ce qui dépasse quelques lignes.