Golang不能用作类型struct array或slice literal

时间:2016-12-27 21:13:41

标签: json go struct slice literals

我试图在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  

1 个答案:

答案 0 :(得分:3)

您的ContentResp类型是切片,而不是结构,但当您使用composite literal尝试创建值时,您将其视为结构体它:

type ContentResp []struct {
    // ...
}

更确切地说,它是一个匿名结构类型的片段。创建匿名结构的值是令人不愉快的,所以你应该创建(name)只有struct的类型,并使用它的一部分,例如:

type ContentResp struct {
    Name        string `json:"name"`
    ContentType string `json:"type"`
    DownloadURL string `json:"download_url"`
}

var contentResps []ContentResp

其他问题:

让我们来看看这个循环:

for _, cont := range contentResp {
    append(contentResp, ...)
}

上面的代码在切片上范围内,并且在其内部它尝试将元素附加到切片。 2个问题:append()返回必须存储的结果(它甚至可能需要分配一个新的,更大的后备数组并复制现有元素,在这种情况下,结果切片将指向一个完全不同的数组,旧的应该被遗弃)。所以它应该像这样使用:

    contentResps = append(contentResps, ...)

第二:你不应该改变你的范围。 for ... range计算范围表达式一次(最多),因此更改它(向其添加元素)将对迭代器代码没有影响(它不会看到切片头更改)。

如果你有这样的情况你有"任务"要完成,但在执行期间可能会出现新任务(要完成,递归),通道是一个更好的解决方案。请参阅此答案以获得渠道感:What are golang channels used for?