Sou*_*uet 5 json struct literals go slice
我正在尝试在 Go 中编写一个函数,该函数采用带有目录 URL 的 JSON 并执行 BFS 以查找该目录中的文件。当我找到作为目录的 JSON 时,代码会生成一个 URL 并且应该将该 URL 加入队列。当我尝试append()在循环中创建结构时,出现错误。
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
Run Code Online (Sandbox Code Playgroud)
您的ContentResp类型是slice,而不是 struct ,但是当您使用复合文字尝试创建它的值时,您将其视为 struct :
type ContentResp []struct {
// ...
}
Run Code Online (Sandbox Code Playgroud)
更准确地说,它是一个匿名结构类型的切片。创建匿名结构的值是令人不快的,因此您应该创建(命名)一个类型仅为struct,并使用它的一部分,例如:
type ContentResp struct {
Name string `json:"name"`
ContentType string `json:"type"`
DownloadURL string `json:"download_url"`
}
var contentResps []ContentResp
Run Code Online (Sandbox Code Playgroud)
进一步的问题:
让我们检查一下这个循环:
for _, cont := range contentResp {
append(contentResp, ...)
}
Run Code Online (Sandbox Code Playgroud)
上面的代码覆盖了一个切片,并在其中尝试将元素附加到切片中。2个问题:append()返回必须存储的结果(它甚至可能必须分配一个新的、更大的后备数组并复制现有元素,在这种情况下,结果切片将指向一个完全不同的数组,旧的应该是弃)。所以它应该像这样使用:
contentResps = append(contentResps, ...)
Run Code Online (Sandbox Code Playgroud)
第二:你不应该改变你所覆盖的切片。的for ... range评估范围表达一次(最多),所以你改变它(将元素添加到它)将具有给迭代代码没有影响(它不会看到切片报头的改变)。
如果你有这样的情况,你有“任务”要完成,但在执行过程中可能会出现新任务(要完成,递归),通道是一个更好的解决方案。看这个回答感受一下channels:golang channels用于什么?