Golang 不能用作类型结构数组或切片文字

Posted

技术标签:

【中文标题】Golang 不能用作类型结构数组或切片文字【英文标题】:Golang cannot use as type struct array or slice literal 【发布时间】:2017-05-12 03:51:52 【问题描述】:

我正在尝试在 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, ContentRespName: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】:

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

type ContentResp []struct 
    // ...

更准确地说,它是一个匿名结构类型的切片。创建匿名结构的值是不愉快的,因此您应该创建(命名)一个只有 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 评估范围表达式 once (最多),因此您更改它(向其中添加元素)对迭代器代码没有影响(它不会看到切片标头更改)。

如果您遇到这样的情况,即您有“任务”要完成,但在执行过程中可能会出现新任务(要以递归方式完成),那么通道是一个更好的解决方案。看这个答案感受一下频道:What are golang channels used for?

【讨论】:

以上是关于Golang 不能用作类型结构数组或切片文字的主要内容,如果未能解决你的问题,请参考以下文章

Golang数组和切片

goLang实现不同类型的切片间互转

Golang✔️走进 Go 语言✔️ 第十二课 结构体 & 切片

Golang✔️走进 Go 语言✔️ 第十二课 结构体 & 切片

golang切片类型

golang快速入门数据类型特别之处(下)