水一篇文章,先上代码:
package main
import (
"fmt"
"reflect"
)
func main() {
result := DoFunc()
fmt.Println(reflect.ValueOf(&result).Elem().Kind())
//out1: interface
result2 := DoFunc2()
fmt.Println(reflect.ValueOf(&result2).Elem().Kind())
//out2: interface
result3 := DoFunc2()
fmt.Println(reflect.ValueOf(result3).Elem().Kind())
//out3: slice
var a = make([]*DemoStruct, 0)
fmt.Println(reflect.ValueOf(&a).Elem().Kind())
//out4: slice
if resultPtr, ok := result.([]*DemoStruct); ok {
fmt.Println(reflect.ValueOf(&resultPtr).Elem().Kind())
//out5: slice
}
}
func DoFunc() interface{} {
return make([]*DemoStruct, 0)
}
func DoFunc2() interface{} {
return &[]*DemoStruct{}
}
type DemoStruct struct {
}
这是我在写低版本go(无泛型)操作 mongodb 的时候遇到的一个问题。因为业务很相似,所以要写公共代码来抽离逻辑,且是低版本 go SDK ,无法使用泛型,所有用 interface 代替。上面代码是抽离出来的部分;
go SDK:1.14
这里的问题是:上面代码示例一共 5个 out,实际解决问题是为了包装类型,达到和 out4一样的返回预期;
**out1、out2的打印值一样的,但是区别是什么?**
**out2、out3的打印值不一样,区别是什么?**
个人的观点:
- out1和out2的打印值都是"interface",这是因为
DoFunc()
和DoFunc2()
都返回的是一个空的接口(interface{})。 - out2和out3的打印值不同是因为它们返回的数据类型不同。
DoFunc2()
返回的是一个指向切片的指针*[]*DemoStruct{}
,而reflect.ValueOf(result3).Elem().Kind()
中的result3
接收了DoFunc2()
的返回值,所以result3
的类型是切片(slice),而不是指针。
所以根据这个例子,能否总结一下函数返回interface(any)的差异?
没写完,遇到了,随手撸的,晚点再更新。
写的有问题的地方,或者描述有错误的地方请帮忙指正;或者有更多见解的,可以评论说一下。