drsl90685154
2017-08-02 16:46
浏览 72
已采纳

从main访问Inner Scope中的Struct数据并在Golang中将其保存到csv

appendStruct function is designed to run in multiple threads in order to collect and append DataItem into DataContainer. So far I can print the result from inner appendStruct Q1: how to access and print container from main, Q2: save that struct data type to csv from 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()

}

OUTPUT from go run test.go is:

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

re Q1. "encoding/csv" has to implement string interface [][]string there is a hint how to approach it in Write struct to csv file but lacks implementation example.

图片转代码服务由CSDN问答提供 功能建议

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

 包main 
 
import“ fmt” 
 
type DataItem结构{
 名称字符串
} 
 
type DataContainer struct {
 Items [] DataItem 
} 
 
func(box * DataContainer)AddItem(item DataItem)[] DataItem {
 box.Items = append(box.Items  ,item)
返回框。Items
} 
 
func appendStruct(){
项目:= [] DataItem {} 
容器:= DataContainer {项目} 
 
 item1:= DataItem {名称:  fmt.Sprintf(“ Item1”)} 
 item2:= DataItem {名称:fmt.Sprintf(“ Item2”)} 
 
 container.AddItem(item1)
 container.AddItem(item2)
 
 var  ss = fmt.Sprintf(“”,container)
 fmt.Println(ss)
} 
 
func main(){
 
 appendStruct()
 
} 
  开始运行的test.go 的pre> 
 
 

OUTPUT是:

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

re Q1。 “ encoding / csv” 必须实现字符串接口 [] [] string ,在将结构写入csv文件 ,但缺少实现示例。

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duanbarong4617 2017-08-02 16:59
    已采纳

    In appendStruct, container is a local variable, so it's not accessible outside that function call. You could return it, which would make it accessible from the caller (in this case, main):

    func appendStruct() DataContainer {
        //...
        return container
    }
    
    func main() {
        container := appendStruct()
    }
    

    The answer you linked is an excellent starting point. A code example shouldn't really be necessary - they're basically recommending that you create a helper method/function that takes all the fields of the struct and puts them into a slice in whatever order you want them to appear in the CSV, e.g.:

    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
    }
    

    Then you can loop over these to write them to a CSV file.

    The error output you're getting is because you're using Sprintf, which expects a format string as the first parameter with a reference for each other argument. You're passing an empty format string, which would only work with no other arguments (and be pointless). Perhaps you meant Sprintf("%v", container) or just Sprint(container)?

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • doukuai3822 2017-08-03 10:49

    Thank you @Adrian, your answer was very helpful. Below is working code:

    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)
    }
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题