可以使用恐慌/恢复作为测试成功类型断言的方法吗?
Posted
技术标签:
【中文标题】可以使用恐慌/恢复作为测试成功类型断言的方法吗?【英文标题】:Is it ok to use panic/recover as a means for testing successful type assertion? 【发布时间】:2015-02-19 01:43:39 【问题描述】:我一直在研究一种尝试解析嵌套 JSON 响应而不将信息映射到预定义结构的方法。
使用空白界面返回:
map[name:My Folder parentId:1 created:2014-10-09T16:32:07+0000 deleted:false description:Sync Dir id:3 links:[map[rel:self entity:folder href:https://web .domain.org/rest/folders/3 id:3] map[href:https://web.domain.org/rest/folders/1 id:1 rel:parent entity:folder] map[entity:user href: https://web.domain.org/rest/users/1 id:1 rel:creator]] 修改时间:2014-12-18T18:07:01+0000 永久链接:https://web.domain.org/w/ SpJYGQkv 可同步:真类型:d userId:1]所以我使用以下内容来浏览这些信息:
func NFind(input interface, refs...interface) (output interface)
defer func() if r := recover(); r != nil output = nil ()
for _, ref := range refs
switch cur := ref.(type)
case string:
output = input.(map[string]interface)[cur]
case int:
output = input.([]interface)[cur]
return output
func NMap(input interface) (output map[string]interface)
defer func() if r := recover(); r != nil ()
if input == nil return nil
return input.(map[string]interface)
func NArray(input interface) (output []interface)
defer func() if r := recover(); r != nil ()
if input == nil return nil
return input.([]interface)
func NString(input interface) (output string)
defer func() if r := recover(); r != nil ()
if input == nil return ""
return input.(string)
func NFloat64(input interface) (output float64)
defer func() if r := recover(); r != nil ()
if input == nil return 0
return input.(float64)
这是从 JSON 字符串中解析信息的可接受方式,还是有更好的方法?
这里是使用上面的例子来解析出我当前使用的正确信息:
func mapCache(input map[string]interface, valType string)
fmt.Println(input)
var (
name string
href string
rel string
links []interface
myMap map[string]interface
)
if name = NString(NFind(input, "name")); name == "" return
if links = NArray(NFind(input, "links")); links == nil return
for i := 0; i < len(links); i++
if myMap = NMap(links[i]); myMap == nil return
if rel = NString(myMap["rel"]); rel == "" return
if rel == "self"
if href = NString(myMap["href"]); href == "" return
CacheDB.Set(valType, name, href, false)
任何见解将不胜感激!谢谢!
【问题讨论】:
【参考方案1】:查看the specification for type assertions:
在特殊形式的赋值或初始化中使用的类型断言
v, ok = x.(T) v, ok := x.(T) var v, ok = x.(T)
产生一个额外的无类型布尔值。如果断言成立,则 ok 的值为真。否则为 false 并且 v 的值为类型 T 的零值。在这种情况下不会发生运行时恐慌。
这比使用错误处理检查类型更快,也更简单。
所以你可以重写
func NMap(input interface) map[string]interface
defer func() if r := recover(); r != nil ()
if input == nil return nil
return input.(map[string]interface)
作为
func NMap(input interface) map[string]interface
if m, ok := input.(map[string]interface); ok
return m
return nil
您也可以考虑使用像 github.com/zazab/zhash 这样的库,以使 map[string]interface
更易于使用。或者,当然,尝试弄清楚encoding/json
的现有模式之一是如何做到的。
【讨论】:
以上是关于可以使用恐慌/恢复作为测试成功类型断言的方法吗?的主要内容,如果未能解决你的问题,请参考以下文章