Go中的嵌套JSON反序列化

I am attempting to convert a nested JSON response to a struct. The struct looks as follows:

type PullRequestEvent struct {
    Action               string   `json:"action"`
    Number               int      `json:"number"`
    PullRequest          struct { 
        Url              string   `json:"url"`
        HtmlUrl          string   `json:"html_url"`
        DiffUrl          string   `json:"diff_url"` 
        Title            string   `json:"title_url"` 
    } `json:"pull_request"`
}

However, only the top-level fields (Action,Number) are being parsed; the rest remain nil or 0. The conversion code is as follows:

func whatever(w http.ResponseWriter, r *http.Request) {
    var ev PullRequestEvent
    dec := json.NewDecoder(r.Body)
    err := dec.Decode(&ev)
    if err != nil {
        // fail request 
    }
}

The JSON is the pull request event here. The relevant parts are

{   
    "action": "closed",   "number": 1,   "pull_request": {
    "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1",
    "id": 191568743,
    "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz",
    "html_url": "https://github.com/Codertocat/Hello-World/pull/1",
    "diff_url": "https://github.com/Codertocat/Hello-World/pull/1.diff",
    "number": 1,
    "state": "closed",
    "locked": false,
    "title": "Update the README with new information",
    "user": {
      "login": "Codertocat",
      "id": 21031067,
      "node_id": "MDQ6VXNlcjIxMDMxMDY3",
      "gravatar_id": "",
      "url": "https://api.github.com/users/Codertocat",
      "html_url": "https://github.com/Codertocat",
      "subscriptions_url": "link",
      "organizations_url": "link",
      "repos_url": "link",
      "events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
      "received_events_url": "link",
      "type": "User",
      "site_admin": false
    }
    //...  }

What is wrong with the code here?

There's no issue with the code you posted, except that there is no field title_url in the response you expect (you probably wanted just title). Here's a playground example that showcases it.

package main

import (
    "bytes"
    "encoding/json"
    "log"
)

const examplePayload = `
{
  "action": "closed",
  "number": 1,
  "pull_request": {
    "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1",
    "id": 191568743,
    "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz",
    "html_url": "https://github.com/Codertocat/Hello-World/pull/1",
    "diff_url": "https://github.com/Codertocat/Hello-World/pull/1.diff",
    "patch_url": "https://github.com/Codertocat/Hello-World/pull/1.patch",
    "issue_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1",
    "number": 1,
    "state": "closed",
    "locked": false,
    "title": "Update the README with new information"
  }
}
`

type PullRequestEvent struct {
    Action      string `json:"action"`
    Number      int    `json:"number"`
    PullRequest struct {
        Url     string `json:"url"`
        HtmlUrl string `json:"html_url"`
        DiffUrl string `json:"diff_url"`
        Title   string `json:"title"`
    } `json:"pull_request"`
}

func main() {
  var ev PullRequestEvent
    ex := bytes.NewReader([]byte(examplePayload))
    if err := json.NewDecoder(ex).Decode(&ev); err != nil {
        log.Fatal(err)
    }
    log.Printf("%#v", ev)
}