每当引用从函数

时间:2018-06-11 10:23:08

标签: json dictionary go error-handling type-assertion

通常会是这样的

func main() {
   my_map := myFunc()
   fmt.Println(my_map)
}

func myFunc() map[string]interface{} {
   // .... create a map....
   return map
}

当我运行这样的模式时,当我尝试打印my_map时,我几乎总是遇到段错误。

如果我返回[]byte类型,也会发生这种情况。

现在就是这样的事情:我认为理解为什么返回[]byte中创建的myFunc()会在main中打印时导致段错误:切片引用在{{}内创建的数组{1}},所以只要myFunc返回,该数组就会被垃圾收集删除,因此会被删除。

我会假设地图上发生了类似的事情。

在C ++中,它只是创建地图的副本,并返回 - >没问题。如果我返回一个数组也一样。

为什么,在go中,我不能简单地返回一个创建的地图,什么是返回地图(在函数内创建)的最佳方法,一旦该函数返回main,就不会导致段错误? / p>

myFunc

1 个答案:

答案 0 :(得分:2)

在Go中的函数内创建的返回值完全正常并且通常使用。编译器使用转义分析,如果它无法证明某个值没有从函数中转义,它将在堆上分配,因此在函数返回时不会被销毁,并且可以在函数返回后使用

错误不能来自打印地图的行(除非它包含递归数据结构,因为它是JSON解组的结果,因此它没有)。可以打印空的甚至是nil地图,并且不会出错。

很可能错误发生在twitterRequest()函数中,可能是在您执行返回值的类型断言时:

return jsonResp.(map[string]interface{})

如果jsonRespnil,或者其保存的值不是map[string]interface{}类型,则此类型断言会导致运行时出现紧急情况。如果响应主体是无效的JSON,它可能是nil,如果响应主体是有效的JSON,它可能是其他类型的值,但它是例如JSON数组。

首先,检查所有错误,包括阅读正文时的错误:

respBody, _ := ioutil.ReadAll(resp.Body)

这样做:

respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
    // Handle error, optionally return
}

您还应该使用断言类型的特殊形式:

m, ok := jsonResp.(map[string]interface{})
if !ok {
    // jsonResp is nil or is not a map!
    // Handle this error case and return
}

return m // all ok

这种类型断言的特殊形式永远不会出现恐慌,相反,如果断言不成立,ok变量将为false,您可以检查并正确处理它。如果oktrue,则表示jsonResp不是nil,其中的值确实是map[string]interface{}类型的值,该值存储在{ {1}},您可以安全返回。