迭代JSON对象数组

I just started learning Go and I'm trying to iterate through each element of array of JSON objects.

I tried the following.

package main

import (
    "encoding/json"
    "fmt"
)

type itemdata []string

func main() {
    var birds itemdata
    birdJson := `[{"species":"pigeon","decription":"likes to perch on rocks"},{"species":"eagle","description":"bird of prey"},{"species":"eagle","description":"bird of prey"}]`

    json.Unmarshal([]byte(birdJson), &birds)
    fmt.Println(len(birds))
    fmt.Println(birds)
    for i := range birds {
        fmt.Println(i)
        fmt.Println(birds[i])
    }

}

How can I iterate on each JSON object?

Expected Output:

0
{"species":"pigeon","decription":"likes to perch on rocks"}
1
{"species":"eagle","description":"bird of prey"}
2
{"species":"eagle","description":"bird of prey"}
package main

import (
    "encoding/json"
    "fmt"
)

type itemdata []struct {    //Precise definition of data structure
    Species     string
    Description string
}

func main() {
    var birds itemdata
    birdJson := `[{"species":"pigeon","description":"likes to perch on rocks"},{"species":"eagle","description":"bird of prey"},{"species":"eagle","description":"bird of prey"}]`

    json.Unmarshal([]byte(birdJson), &birds)
    fmt.Println(len(birds))
    fmt.Println(birds)
    for i, bird := range birds {   //correct syntax for loop
        fmt.Println(i)
        fmt.Println(bird)
    }

}

Playground

Edit:

Your intent to iterate structural data as sequential strings looks very unusual. Sure you can, just construct Decoder and tokeniser.

type itemdata []json.RawMessage //delay unmarshaling of array items
func main() {
    var birds itemdata
    birdJson := `[{"species":"pigeon","description":"likes to perch on rocks"},{"species":"eagle","description":"bird of prey"},{"species":"eagle","description":"bird of prey"}]`
    json.Unmarshal([]byte(birdJson), &birds)
    fmt.Println(len(birds))
    fmt.Println(birds)
    for i, bird := range birds {
        fmt.Println(i)
        dec := json.NewDecoder(bytes.NewReader(bird)) //construct Decoder
        for {
            t, err := dec.Token()  //Tokenise
            if err == io.EOF {
                break
            }
            if _, ok := t.(json.Delim); !ok {
                fmt.Println(t)
            }
        }
    }
}

Playground

package main

import (
    "encoding/json"
    "fmt"
)

type bird struct{
    Species string
    Description string
}

func main() {
    var birds []bird
    birdJson := `[{"species":"pigeon","description":"likes to perch on rocks"},
                  {"species":"eagle","description":"bird of prey"},
                  {"species":"falcon","description":"yet another bird of prey"}]`

    json.Unmarshal([]byte(birdJson), &birds)
    fmt.Println(len(birds))
    fmt.Printf("
%+v

", birds)
    for i := range birds {
        fmt.Printf("%d) %s: %s
", i, birds[i].Species, birds[i].Description)
    }
}

With a correct syntax for looping:

for i,bird := range birds {
    fmt.Printf("%d) %s: %s
", i, bird.Species, bird.Description)
}

EDIT: Is this what you meant?

package main

import (
    "encoding/json"
    "fmt"
)

type bird struct{
    Species string `json:"species"`
    Description string `json:"description"`
}

func main() {
    var birds []bird
    birdJson := `[{"species":"pigeon","description":"likes to perch on rocks"},
                  {"species":"eagle","description":"bird of prey"},
                  {"species":"falcon","description":"yet another bird of prey"}]`

    json.Unmarshal([]byte(birdJson), &birds)
    fmt.Println(len(birds))
    fmt.Printf("
%+v

", birds)
    for _,bird := range birds {
        //fmt.Printf("%d) %s: %s
", i, bird.Species, bird.Description)
        b, _ := json.Marshal(bird)
        fmt.Println(string(b))
    }
}