简体   繁体   English

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

[英]Golang cannot use as type struct array or slice literal

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. 我正在尝试在Go中编写一个函数,该函数采用带有目录URL的JSON并执行BFS在该目录中查找文件。 When I find a JSON that is a directory, the code makes a URL and should enqueue that URL. 当我找到一个作为目录的JSON时,代码将生成一个URL,并应将该URL放入队列。 When I try to create the struct in the append() in the loop, I get errors. 当我尝试在循环的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  

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: 您的ContentResp类型是slice ,而不是结构,但是当您使用复合文字尝试为其创建值时,会将其视为结构:

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, eg: 创建匿名结构的值很不愉快,因此您应该创建(名称)仅是struct的类型,并使用其中的一部分,例如:

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). 这样做有2个问题: append()返回必须存储的结果(它甚至可能必须分配一个新的更大的后备数组并复制现有元素,在这种情况下,结果片将指向一个完全不同的数组,而旧数组将指向旧数组一个应该被放弃)。 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). for ... range 一次 (最多)计算一次范围表达式,因此,对其进行更改(向其中添加元素)将对迭代器代码无效(它将不会看到slice头更改)。

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? 看到以下答案可以了解渠道: golang渠道有什么用途?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM