2017-05-02 3 views
2

J'ai essayé de faire mon propre code pour apprendre comment retourner plusieurs valeurs dans la fonction principale:Quelle est la différence entre ces deux variantes?

package main 

import "fmt" 

func main() { 
    fmt.Println("Enter a integer:") 
    var I int 
    fmt.Scanf("%d", &I) 
    fmt.Println("Accepted:", I) 

    O := half(I) 
    fmt.Println("Returned:", O) 
} 

func half(N int) (int, bool) { 
    var NA int 
    NA = N/2 
    if NA%2 == 0 { 
     fmt.Println("even") 
     return NA, true 
    } else { 
     fmt.Println("odd") 
     return NA, false 
    } 
} 

Et erreur donné: half.go|11| multiple-value half() in single-value context. Cependant, une autre variante travaillent:

package main 

import (
    "fmt" 
) 

func half(number int) (int, bool) { 
    if x := int(number % 2); x == 0 { 
     return x, true 
    } else { 
     return x, false 
    } 
} 

func main() { 
    fmt.Println(half(1)) 
    fmt.Println(half(2)) 
} 

Qu'est-ce que je fais mal? Comment surmonter mon erreur?

Répondre

1

fmt.Printlnfmt.Println accepte tout nombre d'arguments, donc ok accepte les résultats de half.

Dans le premier, vous devez fournir des emplacements pour les deux variables. Soit:

i,b := half(2)

ou

i, _ := half(2)

si vous n'avez pas besoin du deuxième retour.

3

Si une fonction a 2 valeurs de retour, vous devez "attendre" les deux ou rien du tout. Plus sur ce point: Return map like 'ok' in Golang on normal functions

Votre fonction half() a 2 valeurs de retour, de sorte que lorsque vous utilisez un short variable declaration pour stocker les valeurs renvoyées dans les variables, vous devez fournir 2 variables:

O, even := half(I) 
fmt.Println("Returned:", O, even) 

Dans le second cas, vous n'êtes pas stocker les valeurs renvoyées, vous les transmettre à fmt.Println() qui a la signature:

func Println(a ...interface{}) (n int, err error) 

fmt.Println() a un paramètre variadique, de sorte que vous pouvez passer toute num beaucoup d'arguments à ce sujet. Ce qui se passe ici est que toutes les valeurs de retour multiples de half() sont passées en tant que valeur du paramètre variadique de Println(). Ceci est permis et détaillée dans Spec: Calls:

As a special case, if the return values of a function or method g are equal in number and individually assignable to the parameters of another function or method f , then the call f(g(parameters_of_g)) will invoke f after binding the return values of g to the parameters of f in order. The call of f must contain no parameters other than the call of g , and g must have at least one return value. If f has a final ... parameter, it is assigned the return values of g that remain after assignment of regular parameters.

Notez que lorsque vous faites, vous n'êtes pas autorisé à passer/fournir des paramètres supplémentaires, donc par exemple ce qui suit est aussi une erreur de compilation :

fmt.Println("Returned:", half(10)) 
// Error: multiple-value half() in single-value context 

Découvrez ces questions similaires:

Go: multiple value in single-value context

Avoid nesting from conjunction with function that returns 2 values in go?