Reputation: 419
I have the following method which works perfectly fine. Here I am returning an array as an interface.
func ReturnArrayAsInterface1() interface{} {
retval := make([]int, 0)
retval = append(retval, 4, 6, 8, 10)
return retval
}
Consider the following method. Here I want to return the error in case of a panic, so I define the retval
at the beginning and change its value in defer
. But this shows an error "Cannot use 'retval' (type interface{}) as type []Type"
func ReturnArrayAsInterface2() (retval interface{}) {
defer func() {
if r := recover(); r != nil {
retval = r
}
}()
retval = make([]int, 0)
retval = append(retval, 4, 6, 8, 10) . // error here : Cannot use 'retval' (type interface{}) as type []Type
return retval
}
So what I would like to know is, why is it that the first function works fine whereas the second does not? Are there any ways to overcome this?
This also works similarly to Case 2:
func ReturnArrayAsInterface3() interface{} {
var retval interface{}
defer func() {
if r := recover(); r != nil {
retval = r
}
}()
retval = make([]int, 0)
retval = append(retval, 4, 6, 8, 10) . // error here : Cannot use 'retval' (type interface{}) as type []Type
return retval
}
Upvotes: 3
Views: 4101
Reputation: 8696
Case 3 will not work as in Case 2 in case of panic: in case of panic
the return retval
will not run, so nil
will be returned by ReturnArrayAsInterface3
.
To fix Case 2, use a variable with a static type as long as possible because it is safer (catches bugs) and more efficient.
func ReturnArrayAsInterface2() (retval interface{}) {
defer func() {
if r := recover(); r != nil {
retval = r
}
}()
r := make([]int, 0)
retval = append(r, 4, 6, 8, 10)
return
}
Upvotes: 1
Reputation: 417512
Because Go is a statically typed language. Your first example works because type of retval
is []int
, and so you can append int
values to it. You used short variable declaration, so the type of retval
is inferred from the right-hand side expression, which clearly is of type []int
. When you return this []int
value, it will be automatically wrapped in an interface{}
value.
In your second case you use a named result type, where you explicitly specify its type to be interface{}
, and you can't append values to a value of type interface{}
(a non-slice type). It doesn't matter that the dynamic type of the value stored in the retval
interface value is a slice, its static type is interface{}
.
It would work with a type assertion:
retval = append(retval.([]int), 4, 6, 8, 10)
But the first solution is much cleaner and more efficient.
Your third case is almost like the second: you use variable declaration where you explicitly state you want the retval
variable to be of type interface{}
.
Upvotes: 4