空接口,类型断言以及json.Number数据类型

wangyanlb · · 5413 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。
访问一个api, 返回如下数据: ```go { "data": { "trend": { "fields": [ "min_time", "last_px", "avg_px", "business_amount" ], "600570.SS": [ [ 201501090930, 54.98, 54.98, 28327 ], [ 201501090931, 54.63, 54.829486, 49700 ] ] } } } ``` 需要解析 600570.SS 后的json数据,用了 simplejson包 ```go js, err := simplejson.NewJson([]byte(str)) check(err) arr, _ := js.Get("data").Get("trend").Get("600570.ss").Array() ``` 可是对返回的arr数据,用了18般武艺都解析不了。 arr类型理论是一个interface{}类型,但是里面又包含了四组数据,对于这类json数据,网上文档都没有解析的方法。 反复尝试后,用reflect.type 测试了下,发现系统把arr 认定为[]interface 类型,于是类型断言后,遍历。 这回可以把里面数据分拆开了,系统又把里面的数据判断为 json.Number数据类型。 然后就没有然后了.... 经过这一番摸索,对于空接口、类型断言,json包内部的一些设定有了更深的理解:空接口就是因为它灵活,所以在使用时要经过一系列的判断。 上代码: ```go package main import ( "encoding/json" "fmt" "github.com/bitly/go-simplejson" "io/ioutil" "net/http" //"reflect" "regexp" "strconv" "strings" ) //const blkSize int = 10000 type trend struct { date int64 last_px float32 //最新价 avg_px float32 //平均价 volumn float32 //成交量 } var ( lines []string blksLen []int isGB bool ) func check(err error) { if err != nil { panic(err.Error()) } } func Get(url string) ([]byte, error) { defer func() { if err := recover(); err != nil { fmt.Println(err) } }() resp, err := http.Get(url) check(err) //Println(resp.StatusCode) if resp.StatusCode != 200 { panic("FUCK") } return ioutil.ReadAll(resp.Body) } func strip(src string) string { src = strings.ToLower(src) re, _ := regexp.Compile(`<!doctype.*?>`) src = re.ReplaceAllString(src, "") re, _ = regexp.Compile(`<!--.*?-->`) src = re.ReplaceAllString(src, "") re, _ = regexp.Compile(`<script[\S\s]+?</script>`) src = re.ReplaceAllString(src, "") re, _ = regexp.Compile(`<style[\S\s]+?</style>`) src = re.ReplaceAllString(src, "") re, _ = regexp.Compile(`<.*?>`) src = re.ReplaceAllString(src, "") re, _ = regexp.Compile(`&.{1,5};|&#.{1,5};`) src = re.ReplaceAllString(src, "") src = strings.Replace(src, "\r\n", "\n", -1) src = strings.Replace(src, "\r", "\n", -1) return src } func Do(url string) string { body, err := Get(url) check(err) plainText := strip(string(body)) return plainText } func main() { str := Do("http://xxx:8081/quote/v1/trend?prod_code=600570.SS&fields=last_px,business_amount,avg_px") js, err := simplejson.NewJson([]byte(str)) check(err) arr, _ := js.Get("data").Get("trend").Get("600570.ss").Array() t := len(arr) stockdata := trend{} trends := make([]trend, 0, t) for _, v := range arr { //就在这里i进行类型判断 value, _ := v.([]interface{}) for k, u := range value { x, _ := u.(json.Number) //类型断言 y, _ := strconv.ParseFloat(string(x), 64) //将字符型号转化为float64 //v := reflect.ValueOf(k) //fmt.Println("type:", v.Type()) switch k { case 0: stockdata.date = int64(y) case 1: stockdata.last_px = float32(y) case 2: stockdata.volumn = float32(y) case 3: stockdata.avg_px = float32(y) default: fmt.Println("结构体中不存在此元素") } } trends = append(trends, stockdata) } fmt.Println(trends) } ```

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

5413 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传