Valor_
Valor_

Reputation: 3591

How to properly structure struct in struct

I started to learn Go and my (self assigned) mission is to print out a list of hard-coded albums and songs which are on this album.

I've created struct Album which is "object" of album. Inside this struct Album I want to create underlying struct Song. This "object" will hold songs of that album.

My problem/error that I'm getting is ./main.go:46:4: cannot use []Song literal (type []Song) as type Song in field value

This is my code.

// Song struct
type Song struct {
    SongName string `json:"song_name"`
    Position int    `json:"position"`
    Length   string `json:"length"`
}

// Album struct
type Album struct {
    Name        string `json:"name"`
    Artist      string `json:"artist"`
    YouTubeLink string `json:"youtube_link"`
    AlbumImage  string `json:"album_image"`
    Description string `json:"description"`
    ReleaseDate string `json:"release_date"`
    RecordDate  string `json:"record_date"`
    Length      string `json:"length"`
    Studio      string `json:"studio"`
    Songs       Song   `json:"songs"`
}

func listOfAlbums() []Album {

    a := []Album{
        {
            Name:        "The Dark Side of the Moon",
            Artist:      "Pink Floyd",
            YouTubeLink: "https://www.youtube.com/watch?v=HW-lXjOyUWo&list=PLEQdwrAGbxnc9lyYltGRUMt3OgfX0tFbd&index=1",
            AlbumImage:  "https://upload.wikimedia.org/wikipedia/sl/b/bb/Dsotm.jpg",
            Description: "The Dark Side of the Moon is the eighth studio album by English rock band Pink Floyd, released on 1 March 1973 by Harvest Records. Primarily developed during live performances, the band premiered an early version of the record several months before recording began.",
            ReleaseDate: "1973.03.01",
            RecordDate:  "1972.06.01 – 1973.01.01",
            Length:      "42:32",
            Studio:      "Abbey Road Studios, London",
            //
            // Problematic part of code
            //
            Songs: []Song{
                {
                    SongName: "Speak to Me / Breathe",
                    Position: 1,
                    Length:   "1:13",
                },
                {
                    SongName: "Breathe",
                    Position: 2,
                    Length:   "2:43",
                },
                {
                    SongName: "On the run",
                    Position: 3,
                    Length:   "3:36",
                },
                {
                    SongName: "Time",
                    Position: 4,
                    Length:   "6:53",
                },
                {
                    SongName: "The Great Gig in the Sky",
                    Position: 5,
                    Length:   "4:36",
                },
                {
                    SongName: "Money",
                    Position: 6,
                    Length:   "6:23",
                },
                {
                    SongName: "Us and Them",
                    Position: 7,
                    Length:   "7:49",
                },
                {
                    SongName: "Any Colour You Like",
                    Position: 8,
                    Length:   "3:26",
                },
                {
                    SongName: "Brain Damage",
                    Position: 9,
                    Length:   "3:49",
                },
                {
                    SongName: "Eclipse",
                    Position: 10,
                    Length:   "2:03",
                },
            },
        },
    }

    return a
}

Here is a working Go PlayGround code

The questions are following:

  1. Is my logic going in to the right direction? Do I even need to create another struct (Song) or this could be solved in some better manner?
  2. How should I restructure my code so it will be working?

Upvotes: 0

Views: 58

Answers (1)

xarantolus
xarantolus

Reputation: 2029

In your Album struct, a single Song is expected for the Songs field. However, []Song is a slice (list type) of songs. When you update your struct declaration with []Song instead of Song, your definition is good.

type Album struct {
    Name        string `json:"name"`
    Artist      string `json:"artist"`
    YouTubeLink string `json:"youtube_link"`
    AlbumImage  string `json:"album_image"`
    Description string `json:"description"`
    ReleaseDate string `json:"release_date"`
    RecordDate  string `json:"record_date"`
    Length      string `json:"length"`
    Studio      string `json:"studio"`
    Songs       []Song `json:"songs"`
}

Now you can use a []Song{...} for this field, which is also expected in your data definition.

Your code is totally fine and it is normal to use multiple structs for bigger objects that contain other objects.

Upvotes: 2

Related Questions