json.Unmarshal是否要求您的结果结构完全匹配传入的JSON吗?

I have a JSON string I want to unmarshal:

{
  "id":1720,
  "alertId":1,
  "alertName":"{stats} Test Lambda Alert",
  "dashboardId":5,
  "panelId":2,
  "userId":0,
  "newState":"alerting",
  "prevState":"ok",
  "time":1523983581000,
  "text":"",
  "regionId":0,
  "tags":[],
  "login":"",
  "email":"",
  "avatarUrl":"",
  "data":{
    "evalMatches":[
        {
         "metric":"{prod}{stats} Lambda Alert Test",
         "tags":null,
         "value":16.525333333333332
         }
     ]
   }
}

I get the raw stream via a request: bodyBytes, err := ioutil.ReadAll(resp.Body)

I was hoping I could just specify a struct that pulls the values I care about, e.g.,

type Result struct {
    ID string `json:"id"`
    Time int64 `json:"time"`
}

However, when I try this, I get errors.

type Result struct {
    ID   string `json:"id"`
    Time string `json:"time"`
}

var result Result
err2 := json.Unmarshal(bodyBytes, &result)
if err2 != nil {
    log.Fatal(fmt.Sprintf(`Error Unmarshalling: %s`, err2))
}
fmt.Println(result.ID)

Error Unmarshalling: json: cannot unmarshal array into Go value of type main.Result

I suspect this error may be due to what's actually returned from ioutil.ReadAll(), since it has the above JSON string wrapped in [ ] if I do a fmt.Println(string(bodyBytes)), but if I try to json.Unmarshal(bodyBytes[0], &result), I just get compile errors, so I'm not sure.

If I want to unmarshal a JSON string, do I have to specify the full structure in my type Result struct? Is there a way around this? I don't want to be bound to the JSON object I receive (if the API changes upstream, it requires us to modify our code to recognize that, etc.).

You can unmarshal into structs that represent only some fields of your JSON document, but the field types have to match, as the error clearly states:

cannot unmarshal number into Go struct field Result.id of type string

You cannot unmarshal a number into a string. If you define the ID field as any numeric type it'll work just fine:

package main

import (
    "encoding/json"
    "fmt"
)

var j = []byte(`
{
  "id":1720,
  "prevState":"ok",
  "time":1523983581000,
  "text":"",
  "regionId":0
}
`)

type Result struct {
    ID   int   `json:"id"` // or any other integer type, or float{32,64}, or json.Number
    Time int64 `json:"time"`
}

func main() {
    var r Result
    err := json.Unmarshal(j, &r)
    fmt.Println(r, err)
}

Try it on the playground: https://play.golang.org/p/lqsQwLW2dHZ

Update

You have just edited your question with the actual error you receive. You have to unmarshal JSON arrays into slices. So if the HTTP response in fact returns a JSON array, unmarshal into []Result:

var j = []byte(`
[
    {
      "id":1720,
      "prevState":"ok",
      "time":1523983581000,
      "text":"",
      "regionId":0
    }
]
`)

var r []Result
err := json.Unmarshal(j, &r)
fmt.Println(r[0], err)

https://play.golang.org/p/EbOVA8CbcFO

To generate Go types that match your JSON document pretty well, use https://mholt.github.io/json-to-go/.