Reputation: 21
I tried to make my own code for learning how to return multiple values in main function:
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
}
}
And given error: half.go|11| multiple-value half() in single-value context
.
However another variant are working:
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))
}
What am I doing wrong? How to overcome my error?
Upvotes: 2
Views: 91
Reputation: 417672
If a function has 2 return values, you have to "expect" both of them or none at all. More on this: Return map like 'ok' in Golang on normal functions
Your half()
function has 2 return values, so when using a short variable declaration to store the returned values in variables, you have to provide 2 variables:
O, even := half(I)
fmt.Println("Returned:", O, even)
In the second case, you're not storing the returned values, you are passing them to fmt.Println()
which has the signature:
func Println(a ...interface{}) (n int, err error)
fmt.Println()
has a variadic parameter, so you can pass any number of arguments to it. What happens here is that all the multiple return values of half()
are passed as the value of the variadic parameter of Println()
. This is allowed and detailed in 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 methodf
, then the callf(g(parameters_of_g))
will invokef
after binding the return values ofg
to the parameters off
in order. The call off
must contain no parameters other than the call ofg
, andg
must have at least one return value. Iff
has a final...
parameter, it is assigned the return values ofg
that remain after assignment of regular parameters.
Note that when doing so, you are not allowed to pass / provide extra parameters, so for example the following is also a compile-time error:
fmt.Println("Returned:", half(10))
// Error: multiple-value half() in single-value context
Check out these similar questions:
Go: multiple value in single-value context
Avoid nesting from conjunction with function that returns 2 values in go?
Upvotes: 3
Reputation: 23088
fmt.Println
accepts any number of arguments, so is ok accepting the results of half
.
In the first one, you need to provide places for both variables. Either:
i,b := half(2)
or
i, _ := half(2)
if you don't need the second return.
Upvotes: 1