go:关于断言、申请内存的问题

刚接触go,问题可能比较浅显,这里只做一下记录:
今天在敲代码的时候碰到了这样两个问题,来记录分享一下。


断言问题

现在有一个方法,需要传入的参数类型为[]interface{}。已知我现有的数据类型为结构体数组。

// DataToExcel 将数据存入Exel导出
//其中dataList 是一个interface{}类型
func DataToExcel{..., dataList []interface{},...) {
    .......
}

type a struct{
     aa int 
     bb string
     ...
}

func main {}(
     slice := make([]a, 10) 
     DataToExcel(...,slice,...)
)

按照上述情况书写,是允许编译的不会报错。但是当你运行后会panic。
报错:interface{} is not []interface{}

// DataToExcel 将数据存入Exel导出
//其中dataList 是一个interface{}类型
func DataToExcel{..., dataList []interface{},...) {
    .......
}

type a struct{
     aa int 
     bb string
     ...
}

func main {}(
     slice := make([]a, 10) 
     DataToExcel(...,slice.(interface{}),...)
)

按照上述书写,把结构体数组断言成interface,压根就不允许编译。
报错:Invalid type assertion: slice.(interface{}) (non-interface type []interface{} on left)
翻译:无效的类型断言:slice。(interface{})(左侧为非interface{}类型[]interface{})

断言问题的解决:

1.问题原因:

可以肯定的是,我们无法把一个结构体数组类型断言为interface{}。因为slice存的内存结构和存interface是冲突的。类似的说我们无法把8字节的一个单位转成16字节的一个单位是一样的。

2.如何解决:

其实也很好解决,我们只需要把数据从[]interfac{}中一个一个取出来,再append到一个interface{}中就阔以了
这里需要注意在循环遍历你的[]interface{}的时候,用一个变量来接收你的value,如果没有接收,你将只能得到最后一条信息。因为地址一直在变,直到循环结束变成最后一个截至。

var dataList []interface{}
for _, value := range response.List {
    v := value // 注意接收value
    dataList = append(dataList, &v)
}

申请内存问题:

现在有如下三种情况:
1.在func中声明一个结构体指针(当然变量什么的也行)

type s struct {
    a int 
    b string
    ...
}
func a()(m *s){
    ...
    return m
}

2.用var声明一个结构体指针

var a *s

以上这两中方法只是声明,不会分配内存。所以在许多时候会出现各种各样空指针啊,地址无效等错误。之前遇到过错误,现在要来总结反而忘记错误是什么了。回头会在这里补上可能出现的错误。
所以我一般会用下面的方法来声明并且为变量分配内存:
(1):=
(2)make
(3)new
这里不得不再进行以下总结:
newmake二者都是内存的分配(堆上),但是make只用于slice、map以及channel的初始化(非零值);而new用于类型的内存分配,并且内存置为零

这样麻麻再也不用担心我分配不到内存了~~~~

推荐阅读更多精彩内容