恐慌:接口转换错误:接口{}是字符串,而不是float64。

huangapple go评论85阅读模式
英文:

panic: interface conversion: interface {} is string, not float64

问题

你在将这个简单的 Python 函数转换为 Golang 时遇到了问题。错误信息是 panic: interface conversion: interface {} is string, not float64

以下是 Python 代码:

def binance(crypto: str, currency: str):
    import requests

    base_url = "https://www.binance.com/api/v3/avgPrice?symbol={}{}"
    base_url = base_url.format(crypto, currency)
  
    try:
        result = requests.get(base_url).json()
        print(result)
        result = result.get("price")
    except Exception as e:
        return False
    return result

以下是 Golang 代码(比应有的代码更长且更复杂):

func Binance(crypto string, currency string) (float64, error) {
	req, err := http.NewRequest("GET", fmt.Sprintf("https://www.binance.com/api/v3/avgPrice?symbol=%s%s", crypto, currency), nil)
	if err != nil {
		 fmt.Println("Error is req: ", err)
	}
	
	client := &http.Client{}
	
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("error in send req: ", err)
	}
	respBody, _ := ioutil.ReadAll(resp.Body)
	var respMap map[string]interface{}
	log.Printf("body=%v",respBody)
	json.Unmarshal(respBody,&respMap) 
	log.Printf("response=%v",respMap)
	price := respMap["price"]
	log.Printf("price=%v",price)

	pricer := price.(float64)
	return pricer, err
}

你在这里出了什么问题?之前你遇到了错误 cannot use price (type interface {}) as type float64 in return argument: need type assertion,然后你尝试了类型断言 pricer := price.(float64),现在又出现了这个错误 panic: interface conversion: interface {} is string, not float64

请注意,Golang 中的类型断言是一种将接口类型转换为具体类型的操作。在这种情况下,你尝试将 price 接口类型转换为 float64 类型,但实际上 price 是一个字符串类型。

这是因为在 Python 代码中,result.get("price") 返回的是一个字符串,而不是一个浮点数。因此,在 Golang 代码中,你需要将 price 的类型断言为字符串类型,而不是浮点数类型。你可以使用 price.(string) 进行类型断言。

修正后的 Golang 代码如下:

func Binance(crypto string, currency string) (string, error) {
	req, err := http.NewRequest("GET", fmt.Sprintf("https://www.binance.com/api/v3/avgPrice?symbol=%s%s", crypto, currency), nil)
	if err != nil {
		 fmt.Println("Error is req: ", err)
	}
	
	client := &http.Client{}
	
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("error in send req: ", err)
	}
	respBody, _ := ioutil.ReadAll(resp.Body)
	var respMap map[string]interface{}
	log.Printf("body=%v",respBody)
	json.Unmarshal(respBody,&respMap) 
	log.Printf("response=%v",respMap)
	price := respMap["price"]
	log.Printf("price=%v",price)

	pricer := price.(string)
	return pricer, err
}

这样,你应该能够正确地将 price 转换为字符串类型并返回它,而不会出现类型转换错误。

英文:

I am trying to convert this simple python function to golang, but facing issues with this error

panic: interface conversion: interface {} is string, not float64

python

def binance(crypto: str, currency: str):
    import requests

    base_url = "https://www.binance.com/api/v3/avgPrice?symbol={}{}"
    base_url = base_url.format(crypto, currency)
  
    try:
        result = requests.get(base_url).json()
        print(result)
        result = result.get("price")
    except Exception as e:
        
        return False
    return result

here is the golang version(longer code and more complicated code than should be)

func Binance(crypto string, currency string) (float64, error) {
	req, err := http.NewRequest("GET", fmt.Sprintf("https://www.binance.com/api/v3/avgPrice?symbol=%s%s", crypto, currency), nil)
	if err != nil {
		 fmt.Println("Error is req: ", err)
	}
	
	client := &http.Client{}
	
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("error in send req: ", err)
	}
	respBody, _ := ioutil.ReadAll(resp.Body)
	var respMap map[string]interface{}
	log.Printf("body=%v",respBody)
	json.Unmarshal(respBody,&respMap) 
	log.Printf("response=%v",respMap)
	price := respMap["price"]
	log.Printf("price=%v",price)

	pricer := price.(float64)
	return pricer, err
}

so what am I getting wrong here? Previously i had the error cannot use price (type interface {}) as type float64 in return argument: need type assertion and now i tried the type assertion with pricer := price.(float64) and now this error

panic: interface conversion: interface {} is string, not float64

答案1

得分: 5

在错误信息中告诉你,price 是一个字符串,而不是一个 float64 类型,所以你需要进行如下操作(假设):

pricer := price.(string)
return strconv.ParseFloat(pricer, 64)

更好的方法可能是使用以下方式:

type response struct {
    Price float64 `json:",string"`
}
r := &response{}
respBody, _ := ioutil.ReadAll(resp.Body)
err := json.Unmarshal(respBody, r) 
return r.Price, err

"string" 选项表示该字段以 JSON 形式存储在 JSON 编码的字符串中。它仅适用于字符串、浮点数、整数或布尔类型的字段。

参考链接:https://pkg.go.dev/encoding/json#Marshal

英文:

It's telling you in the error, price is a string, not a float64, so you need to do (presumably):

pricer := price.(string)
return strconv.ParseFloat(pricer, 64)

A better way would probably be to instead do

type response struct {
    Price float64 `json:",string"`
}
r := &response{}
respBody, _ := ioutil.ReadAll(resp.Body)
err := json.Unmarshal(respBody, r) 
return r.Price, err

> The "string" option signals that a field is stored as JSON inside a JSON-encoded string. It applies only to fields of string, floating point, integer, or boolean types.

https://pkg.go.dev/encoding/json#Marshal

答案2

得分: 3

错误已经告诉你了:price 是一个字符串。所以它可能来自一个看起来像这样的 JSON:

{
   "price": "123"
}

而不是

{
   "price": 123
}

第一个解析为字符串。第二个解析为 float64。

在你的情况下,你需要解析它:

pricer, err := strconv.ParseFloat(price.(string), 64)
英文:

The error already tells you: price is a string. So it is probably coming from a JSON that looks like:

{
   "price": "123"
}

but not

{
   "price": 123
}

The first unmarshals as string. The second unmarshals as float64.

In your case, you have to parse it:

    pricer,err := strconv.ParseFloat(price.(string),64)

huangapple
  • 本文由 发表于 2022年1月7日 05:10:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/70613644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定