I'm trying to write a function in Go that takes a JSON with URLs of a directory and perform BFS to find files in that directory. When I find a JSON that is a directory, the code makes a URL and should enqueue that URL. When I try to create the struct in the append()
in the loop, I get errors.
type ContentResp []struct {
Name string `json:"name"`
ContentType string `json:"type"`
DownloadURL string `json:"download_url"`
}
...
var contentResp ContentResp
search(contentQuery, &contentResp)
for _, cont := range contentResp {
append(contentResp, ContentResp{Name:cont.Name, ContentType:"dir", DownloadURL:cont.contentDir.String()})
}
./bfs.go:129: undefined: Name
./bfs.go:129: cannot use cont.Name (type string) as type struct { Name string "json:\"name\""; ContentType string "json:\"type\""; DownloadURL string "json:\"download_url\"" } in array or slice literal
./bfs.go:129: undefined: ContentType
./bfs.go:129: cannot use "dir" (type string) as type struct { Name string "json:\"name\""; ContentType string "json:\"type\""; DownloadURL string "json:\"download_url\"" } in array or slice literal
./bfs.go:129: undefined: DownloadURL
./bfs.go:129: cannot use cont.contentDir.String() (type string) as type struct { Name string "json:\"name\""; ContentType string "json:\"type\""; DownloadURL string "json:\"download_url\"" } in array or slice literal
Your
ContentResp
type is a slice, not a struct, yet you're treating it as a struct when you use a composite literal trying to create a value of it:More precisely it's a slice of a type which is an anonymous struct. Creating values of anonymous structs are unpleasant, so instead you should create (name) a type being only the
struct
, and use a slice of this, e.g.:Further issues:
Let's examine this loop:
The code above ranges over a slice, and inside it it tries to append elements to the slice. 2 issues with this:
append()
returns the result which must be stored (it might even have to allocate a new, bigger backing array and copy existing elements over, in which case the result slice will point to a completely different array and the old one should be abandoned). So it should be used like this:Second: you shouldn't change the slice you're ranging over. The
for ... range
evaluates the range expression once (at most), so you changing it (adding elements to it) will have no effect to the iterator code (it will not see the slice header changes).If you have such a case where you have "tasks" to be completed, but during execution new tasks may arise (to be completed, recursively), a channel is a much better solution. See this answer to get a feeling of channels: What are golang channels used for?