doumi7861 2016-12-27 21:13
浏览 114
已采纳

Golang不能用作类型struct数组或slice文字

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  
  • 写回答

1条回答 默认 最新

  • douyuai8994 2016-12-27 21:20
    关注

    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:

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

    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.:

    type ContentResp struct {
        Name        string `json:"name"`
        ContentType string `json:"type"`
        DownloadURL string `json:"download_url"`
    }
    
    var contentResps []ContentResp
    

    Further issues:

    Let's examine this loop:

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

    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:

        contentResps = append(contentResps, ...)
    

    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?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器