在Golang中从main访问内部作用域中的结构数据并保存到csv

在Golang中从main访问内部作用域中的结构数据并保存到csv,csv,go,Csv,Go,appendStruct函数设计为在多个线程中运行,以便收集DataItem并将其附加到DataContainer中。到目前为止,我可以从内部appendStructQ1:如何从main访问和打印container,Q2:从main将该结构数据类型保存到csv package main import "fmt" type DataItem struct { name string } type DataContainer struct { Items []DataItem

appendStruct
函数设计为在多个线程中运行,以便收集
DataItem
并将其附加到
DataContainer
中。到目前为止,我可以从内部
appendStruct
Q1:如何从
main
访问和打印
container
,Q2:从
main
将该结构数据类型保存到
csv

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()

}
运行测试的输出为:

%!(EXTRA main.DataContainer={[{Item1} {Item2}]})

关于Q1<代码>“encoding/csv”必须实现字符串接口
[]string
中有一个如何实现它的提示,但缺少实现示例

appendStruct
中,
container
是一个局部变量,因此在该函数调用之外无法访问它。您可以返回它,这将使调用者可以访问它(在本例中,
main
):

您链接的答案是一个很好的起点。代码示例应该不是必需的-他们基本上建议您创建一个助手方法/函数,该方法/函数接受结构的所有字段,并按照您希望它们在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)

appendStruct
中,
container
是一个局部变量,因此在该函数调用之外无法访问它。您可以返回它,这将使调用者可以访问它(在本例中,
main
):

您链接的答案是一个很好的起点。代码示例应该不是必需的-他们基本上建议您创建一个助手方法/函数,该方法/函数接受结构的所有字段,并按照您希望它们在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)

谢谢@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)
}

谢谢你,阿德里安,你的回答很有帮助。以下是工作代码:

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

appendStruct
返回
container
。您能告诉我解决方案吗?我是新来的
golang
。我将有多个
appendStruct
线程将数据写入
container
,因此在它们全部完成后需要访问它。请从
appendStruct
返回
container
。您是否能找到解决方案?我是新来的
golang
。我将有多个
appendStruct
线程将数据写入
container
,因此需要在它们全部完成时访问它。