appendStruct
函数旨在在多个线程中运行,以便将DataItem
收集并附加到DataContainer
中。到目前为止,我可以打印内部appendStruct
Q1的结果:如何从container
访问和打印main
,Q2:将结构数据类型保存到csv
{{1} }
main
来自package main
import "fmt"
type DataItem struct {
name string
}
type DataContainer struct {
Items []DataItem
}
func (box *DataContainer) AddItem(item DataItem) []DataItem {
box.Items = append(box.Items, item)
return box.Items
}
func appendStruct() {
items := []DataItem{}
container := DataContainer{items}
item1 := DataItem{name: fmt.Sprintf("Item1")}
item2 := DataItem{name: fmt.Sprintf("Item2")}
container.AddItem(item1)
container.AddItem(item2)
var ss = fmt.Sprintf("", container)
fmt.Println(ss)
}
func main() {
appendStruct()
}
的输出是:
go run test.go
第一季度。 %!(EXTRA main.DataContainer={[{Item1} {Item2}]})
必须实现字符串接口"encoding/csv"
,有一个提示如何在Write struct to csv file
中处理它但缺少实现示例。
答案 0 :(得分:2)
在appendStruct
中,container
是一个局部变量,因此在函数调用之外无法访问它。您可以返回它,这将使其可以从调用者访问(在本例中为main
):
func appendStruct() DataContainer {
//...
return container
}
func main() {
container := appendStruct()
}
你联系的答案是一个很好的起点。代码示例不应该是必要的 - 他们基本上建议你创建一个辅助方法/函数,它接受结构的所有字段,并按照你希望它们出现的顺序将它们放入一个切片中。 CSV,例如:
func (c DataItem) ToSlice() []string {
row := make([]string, 1, 1) // Since you only have 1 field in the struct
row[0] = c.name
return row
}
然后你可以遍历这些以将它们写入CSV文件。
您获得的错误输出是因为您正在使用Sprintf
,它希望格式字符串作为第一个参数,并为每个其他参数提供参考。您正在传递一个空格式字符串,该字符串只能用于其他参数(并且没有意义)。也许你的意思是Sprintf("%v", container)
或只是Sprint(container)
?
答案 1 :(得分:0)
谢谢@Adrian,你的回答非常有帮助。以下是工作代码:
package main
import (
"fmt"
"os"
"encoding/csv"
"log"
)
type DataItem struct {
name string
}
type DataContainer struct {
Items []DataItem
}
func (box *DataContainer) AddItem(item DataItem) []DataItem {
box.Items = append(box.Items, item)
return box.Items
}
func appendStruct() DataContainer{
items := []DataItem{}
container := DataContainer{items}
item1 := DataItem{name: fmt.Sprintf("Item1")}
item2 := DataItem{name: fmt.Sprintf("Item2")}
container.AddItem(item1)
container.AddItem(item2)
return container
}
func (c DataItem) ToSlice() []string {
row := make([]string, 1, 1)
row[0] = c.name
return row
}
func checkError(message string, err error) {
if err != nil {
log.Fatal(message, err)
}
}
func main() {
container := appendStruct()
var ss = fmt.Sprint(container)
println(ss)
file, err := os.Create("result.csv")
checkError("Cannot create file", err)
defer file.Close()
w := csv.NewWriter(file)
for _, record := range container.Items {
values := record.ToSlice()
if err := w.Write(values); err != nil {
log.Fatalln("error writing record to csv:", err)
}
}
w.Flush()
if err := w.Error(); err != nil {
log.Fatal(err)
}