2017-08-02 46 views
0

appendStruct函數被設計爲在多個線程中運行,以便收集和追加DataItemDataContainer。到目前爲止,我可以從內部打印結果appendStruct Q1:如何從main訪問和打印container,Q2:將結構數據類型從main保存到csv?從go run test.go在main範圍內訪問內部範圍內的結構數據並在Golang中保存爲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有一個提示如何在Write struct to csv file 中接近它,但缺少實現示例。

+1

從'appendStruct'返回'container'。 – RayfenWindspear

+0

請問你能解決這個問題嗎?我是'golang'的新手。我將有多個'appendStruct'線程將數據寫入'container',所以當它們全部完成時需要被訪問。 –

回答

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)

0

謝謝@阿德里安,你的回答非常有幫助。以下是工作代碼:

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