背景:

初学golang,在demo项目中接入sms短信服务,需要通过第三方的接口校验验证码。
共使用到以下三个包:

	"encoding/json"		//json解析相关
	"io/ioutil"			//解析httpResponse的body
	"net/http"			//发起http请求
//校验收到的验证码
func VerifyCode(phone, code string) (bool, error) {
	// json
	contentType := "application/json"
	data := mapToJSON(&map[string]interface{}{
		"phone":  phone,
		"code":   code,
		"appkey": APP_KEY,
		"zone":   DEFAULT_ZONE,
	})
	resp, err := http.Post(VERIFY_URL, contentType, strings.NewReader(data))
	if err != nil {
		fmt.Printf("post failed, err:%v\n", err)
		return false, err
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("get resp failed, err:%v\n", err)
		return false, err
	}

	//json序列化成map 解析MOB验证接口的返回值
	var tempMap map[string]interface{}

	err = json.Unmarshal([]byte(b), &tempMap)

	if err != nil {
		fmt.Printf("parse resp failed, err:%v\n", err)
		return false, err
	}

	//根据接口返回状态码 判断验证码结果
	switch tempMap["status"] {
	case 200:		
		return true, nil
	case 405:
		fmt.Println("code 405 int")
		return true, nil
	default:
		return false,errors.New(tempMap["error"].(string))
	}
}
出现的问题:
200、468如{"status":200}、{"status":468,"error":"Illegal check request."}
	case 200:		
		return true, nil
	case 405:
		fmt.Println("code 405 int")
		return true, nil
	default:
		return false,errors.New(tempMap["error"].(string))

结果发现switch始终走的都是default分支,调试发现这里解析得到的status根本不是int型的,而是float64:
在这里插入图片描述

正是因此,switch没有进入200或者其他状态码的分支,于是可以对代码进行修改:

switch int(tempMap["status"].(float64)) 

先对map中value类型为interface{}的数据进行float64的断言,再通过强转变为int类型,于是能够正确地进入switch分支。

JSON解析数据的类型规则
func Unmarshal(data []byte, v interface{})map[string]interface{}
  1. bool, for JSON booleans

  2. float64, for JSON numbers //这就是本次问题产生的原因

  3. string, for JSON strings

  4. []interface{}, for JSON arrays

  5. map[string]interface{}, for JSON objects

  6. nil for JSON null