在Go中追加结构片

I have two structs, like so:

// init a struct for a single item
type Cluster struct {
  Name string
  Path string
}

// init a grouping struct
type Clusters struct {
  Cluster []Cluster
}

What I want to do is append to new items to the clusters struct. So I wrote a method, like so:

func (c *Clusters) AddItem(item Cluster) []Cluster {
  c.Cluster = append(c.Cluster, item)
  return c.Cluster
}

The way my app works, I loop through some directories then append the name of the final directory and it's path. I have a function, that is called:

func getClusters(searchDir string) Clusters {

  fileList := make([]string, 0)
  //clusterName := make([]string, 0)
  //pathName := make([]string, 0)

  e := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
    fileList = append(fileList, path)
    return err
  })

  if e != nil {
    log.Fatal("Error building cluster list: ", e)
  }

  for _, file := range fileList {

    splitFile := strings.Split(file, "/")
    // get the filename
    fileName := splitFile[len(splitFile)-1]

    if fileName == "cluster.jsonnet" {
      entry := Cluster{Name: splitFile[len(splitFile)-2], Path: strings.Join(splitFile[:len(splitFile)-1], "/")}
      c.AddItem(entry)

    }
  }
  Cluster := []Cluster{}
  c := Clusters{Cluster}

  return c

}

The problem here is that I don't know the correct way to do this.

Currently, I'm getting:

cmd/directories.go:41:4: undefined: c

So I tried moving this:

Cluster := []Cluster{}
c := Clusters{Cluster}

Above the for loop - range. The error I get is:

cmd/directories.go:43:20: Cluster is not a type

What am I doing wrong here?

The error is in the loop where you are calling AddItem function on Cluster method receiver which is not defined inside getClusters function. Define Cluster struct before for loop and then call the function c.AddItem as defined below:

func getClusters(searchDir string) Clusters {

    fileList := make([]string, 0)
    fileList = append(fileList, "f1", "f2", "f3")

    ClusterData := []Cluster{}
    c := Clusters{Cluster: ClusterData} // change the struct name passed to Clusters struct

    for _, file := range fileList {

        entry := Cluster{Name: "name" + file, Path: "path" + file}
        c.AddItem(entry)
    }
    return c

}

you have defined the same struct name to Clusters struct that's why the error

cmd/directories.go:43:20: Cluster is not a type

Checkout working code on Go playground

In Golang Composite literal is defined as:

Composite literals construct values for structs, arrays, slices, and maps and create a new value each time they are evaluated. They consist of the type of the literal followed by a brace-bound list of elements. Each element may optionally be preceded by a corresponding key.

Also Have a look on struct literals section defined in above link for Compositeliterals to get more description.

You need to define c before entering the loop in which you use it.

The Cluster is not a type error is due to using the same Cluster name as the type and the variable, try using a different variable name.

clusterArr := []Cluster{}
c := Clusters{clusterArr}

for _, file := range fileList {
   ....
}