刚接触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
这里不得不再进行以下总结:
new
和make
二者都是内存的分配(堆上),但是make只用于slice、map以及channel的初始化(非零值);而new用于类型的内存分配,并且内存置为零
这样麻麻再也不用担心我分配不到内存了~~~~