一个 Go interface 反射问题的瓜,周一提提神

50 阅读1分钟

水一篇文章,先上代码:

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一样的返回预期;

  1. **out1、out2的打印值一样的,但是区别是什么?**
  2. **out2、out3的打印值不一样,区别是什么?**

个人的观点:

  1. out1和out2的打印值都是"interface",这是因为DoFunc()DoFunc2()都返回的是一个空的接口(interface{})。
  2. out2和out3的打印值不同是因为它们返回的数据类型不同。DoFunc2()返回的是一个指向切片的指针*[]*DemoStruct{},而reflect.ValueOf(result3).Elem().Kind()中的result3接收了DoFunc2()的返回值,所以result3的类型是切片(slice),而不是指针。

所以根据这个例子,能否总结一下函数返回interface(any)的差异?

没写完,遇到了,随手撸的,晚点再更新。

写的有问题的地方,或者描述有错误的地方请帮忙指正;或者有更多见解的,可以评论说一下。