Go v1.4.0版本Google Maps API JSON反序列化问题的解决办法?
临时解决Google Maps Go API v1.4.0反序列化secondary_opening_hours的问题
问题背景
你遇到的是Google Maps Place Details API返回字段类型不匹配导致的JSON反序列化错误:官方Go SDK v1.4.0的PlaceDetailsResult结构体中,secondary_opening_hours字段被定义为单个maps.OpeningHours对象,但部分Place ID对应的API响应里该字段是数组类型,直接调用PlaceDetails方法会抛出json: cannot unmarshal array into Go struct field PlaceDetailsResult.result.secondary_opening_hours of type maps.OpeningHours错误。
临时修复方案
以下是两种可行的临时解决办法:
方法1:自定义结构体直接请求API
绕过官方SDK的反序列化逻辑,直接通过HTTP请求获取响应,用兼容数组的自定义结构体解析:
package main import ( "context" "encoding/json" "fmt" "net/http" "net/url" "googlemaps.github.io/maps" ) // 自定义兼容的详情结构体,将secondary_opening_hours设为数组类型 type CustomPlaceDetails struct { Result struct { Name string `json:"name"` SecondaryOpeningHours []maps.OpeningHours `json:"secondary_opening_hours,omitempty"` // 根据需求添加其他需要的字段 } `json:"result"` } func main() { apiKey := "AIz....1c" placeID := "ChIJZ8MeRRouTI8REZAMtusUH3I" // 构造Place Details API请求URL baseURL, _ := url.Parse("https://maps.googleapis.com/maps/api/place/details/json") params := url.Values{} params.Set("place_id", placeID) params.Set("key", apiKey) baseURL.RawQuery = params.Encode() req, _ := http.NewRequestWithContext(context.Background(), "GET", baseURL.String(), nil) resp, err := http.DefaultClient.Do(req) if err != nil { fmt.Println(err) return } defer resp.Body.Close() var customResp CustomPlaceDetails if err := json.NewDecoder(resp.Body).Decode(&customResp); err != nil { fmt.Println(err) return } fmt.Printf("地点名称:%s\n", customResp.Result.Name) if len(customResp.Result.SecondaryOpeningHours) > 0 { fmt.Printf("备用营业时间:%v\n", customResp.Result.SecondaryOpeningHours[0]) } }
方法2:本地修改SDK结构体(补丁方案)
如果需要保留官方SDK的大部分功能,可以临时修改SDK的结构体定义:
- 找到本地SDK安装路径(通常为
$GOPATH/pkg/mod/googlemaps.github.io/maps@v1.4.0/place.go) - 打开
place.go,找到PlaceDetailsResult结构体,将SecondaryOpeningHours字段的类型从OpeningHours改为[]OpeningHours:
type PlaceDetailsResult struct { // 保留原有其他字段 SecondaryOpeningHours []OpeningHours `json:"secondary_opening_hours,omitempty"` // 保留原有其他字段 }
- 重新编译项目即可适配数组类型的响应。注意:后续更新SDK后需要重新打补丁。
说明
两种方案均为临时规避手段,优先推荐方法1(无需修改SDK,灵活性更高),方法2适合依赖SDK其他功能的场景。
内容的提问来源于stack exchange,提问作者Cedric
相关产品推荐
相关产品推荐

