从主要访问内部范围中的结构数据并在Golang中保存到csv

时间:2017-08-02 16:46:49

标签: csv go

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 中处理它但缺少实现示例。

2 个答案:

答案 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)
}