亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go?CSV包實現(xiàn)結構體和csv內(nèi)容互轉工具詳解

 更新時間:2023年03月14日 10:28:37   作者:Go學堂  
這篇文章主要介紹了Go?CSV包實現(xiàn)結構體和csv內(nèi)容互轉工具詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

大家在開發(fā)中一定遇到過將數(shù)據(jù)導出成csv格式文件的需求。go標準庫中的csv包是只能寫入字符串類型的切片。而在go中一般都是將內(nèi)容寫入到結構體中。所以,若使用標準的csv包,就需要將結構體先轉換成對應的字符串類型,再寫入文件。那可不可以將結構體對象直接輸出成csv格式內(nèi)容呢?

今天給大家推薦的就是一個能將結構體和csv內(nèi)容進行快速互轉的工具包:gocsv

gocsv小檔案

gocsv 小檔案
star1.5 kused by1.6k
contributors80作者gocarina
功能簡介提供一個簡單、高效地將csv內(nèi)容和結構體進行互轉的功能
項目地址github.com/gocarina/go…
相關知識reflect、結構體tag

gocsv的基本功能

gocsv包的最基本的作用就是能夠方便的將csv內(nèi)容轉換到對應的結構體上,或者將結構體的內(nèi)容快速的轉換成csv格式(包括寫入文件)。

gocsv.UnmarshalFile函數(shù):csv內(nèi)容轉成結構體

假設文件中的內(nèi)容如下:

client_id,client_name,client_age
1,Jose,42
2,Daniel,26
3,Vincent,32

然后從文件中讀取出內(nèi)容,并直接轉換到結構體Client上,如下:

package main
import (
	"fmt"
	"os"
	"github.com/gocarina/gocsv"
)
type NotUsed struct {
	Name string
}
type Client struct { // Our example struct, you can use "-" to ignore a field
	Id            string `csv:"client_id"`
	Name          string `csv:"client_name"`
	Age           string `csv:"client_age"`
	NotUsedString string `csv:"-"`
	NotUsedStruct NotUsed `csv:"-"` 
}
func main() {
	clientsFile, err := os.OpenFile("clients.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		panic(err)
	}
	defer clientsFile.Close()
	clients := []*Client{}
	if err := gocsv.UnmarshalFile(clientsFile, &clients); err != nil { // Load clients from file
		panic(err)
	}
	for _, client := range clients {
		fmt.Println("Hello", client.Name)
	}
}

gocsv.MarshalFile函數(shù):結構體轉成csv文件

package main
import (
	"fmt"
	"os"
	"github.com/gocarina/gocsv"
)
type NotUsed struct {
	Name string
}
type Client struct { // Our example struct, you can use "-" to ignore a field
	Id            string `csv:"client_id"`
	Name          string `csv:"client_name"`
	Age           string `csv:"client_age"`
	NotUsedString string `csv:"-"`
	NotUsedStruct NotUsed `csv:"-"` 
}
func main() {
	clientsFile, err := os.OpenFile("clients.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		panic(err)
	}
	defer clientsFile.Close()
	clients := []*Client{}
	clients = append(clients, &Client{Id: "12", Name: "John", Age: "21"}) // Add clients
	clients = append(clients, &Client{Id: "13", Name: "Fred"})
	clients = append(clients, &Client{Id: "14", Name: "James", Age: "32"})
	clients = append(clients, &Client{Id: "15", Name: "Danny"})
	err = gocsv.MarshalFile(&clients, clientsFile) // Use this to save the CSV back to the file
	if err != nil {
		panic(err)
	}
}

自定義類型轉換器

gocsv包還可以給自定義的結構體類型定義csv和結構體的互轉函數(shù)。只要自定義的類型實現(xiàn)如下接口即可:

type TypeMarshaller interface {
	MarshalCSV() (string, error)
}
// TypeUnmarshaller is implemented by any value that has an UnmarshalCSV method
// This converter is used to convert a string to your value representation of that string
type TypeUnmarshaller interface {
	UnmarshalCSV(string) error
}

或者將結構體轉換成csv字符串時,需要實現(xiàn)如下接口:

// MarshalText encodes the receiver into UTF-8-encoded text and returns the result.
type TextMarshaler interface {
	MarshalText() (text []byte, err error)
}
type TextUnmarshaler interface {
	UnmarshalText(text []byte) error
}

例如,我們定義了一個結構體DateTime,里面有一個time.Time類型的屬性。并且DateTime類型實現(xiàn)了TypeMarshaller接口的MarshalCSV函數(shù)和TypeUnmarshaller接口的UnmarshalCSV函數(shù)。如下:

type DateTime struct {
	time.Time
}
// Convert the internal date as CSV string
func (date *DateTime) MarshalCSV() (string, error) {
	return date.Time.Format("20060201"), nil
}
// You could also use the standard Stringer interface 
func (date *DateTime) String() (string) {
	return date.String() // Redundant, just for example
}
// Convert the CSV string as internal date
func (date *DateTime) UnmarshalCSV(csv string) (err error) {
	date.Time, err = time.Parse("20060201", csv)
	return err
}
type Client struct { // Our example struct with a custom type (DateTime)
	Id       string   `csv:"id"`
	Name     string   `csv:"name"`
	Employed DateTime `csv:"employed"`
}
func main() {
	client := []Client{
		{
			Id: "001",
			Name: "Go學堂",
			Employed: DateTime{time.Now()},
		},
	}
	csvContent, _ := gocsv.MarshalString(client)
	fmt.Println("csv:", csvContent) //輸出內(nèi)容是 001,Go學堂,20231003
}

當我們運行上述代碼,最終的輸出內(nèi)容是:

001,Go學堂,20231003

最后的日期就是按DateTime的MarshalCSV函數(shù)格式輸出的。

自定義CSV的Reader/Writer

在開頭處我們提到,csv文件中的分隔符默認是逗號。但也可以是其他字符。這就要求我們在讀取或寫入之前指定好內(nèi)容的分隔號。那么就可以通過自定義的Reader/Writer來覆蓋默認的Reader/Writer的選項。如下:

  • 指定讀取內(nèi)容的分割符是 "|"
gocsv.SetCSVReader(func(in io.Reader) gocsv.CSVReader {
    r := csv.NewReader(in)
	r.Comma = '|'
    return r // Allows use pipe as delimiter
})
  • 指定寫入的內(nèi)容是用 分割符 "|" 進行分割的
gocsv.SetCSVWriter(func(out io.Writer) *gocsv.SafeCSVWriter {
	writer := csv.NewWriter(out)
    writer.Comma = '|'
    return gocsv.NewSafeCSVWriter(writer)
})

gocsv包的特點總結

1、結構體切片和csv內(nèi)容互轉。能夠將結構體切片(或數(shù)組)直接輸出成csv內(nèi)容或輸出到文件。反之亦然。

2、csv標簽。其轉換過程是通過結構體上的“csv”標簽進行關聯(lián)的。

3、csv標簽對應csv內(nèi)容表頭。當結構體和csv格式互轉時,結構體中的csv標簽對應的就是csv表格的表頭,結構體中的字段順序對應的就是csv文件列的順序。

4、底層依然是使用標準庫中的csv。在寫入csv文件時,底層實際上用的還是go標準庫中的encoding/csv/Writer結構體的Write(row []string)方法。

5、自動將結構體字段的類型轉換成字符串:大家看到標準csv包中的Write方法的入?yún)⑹莝tring類型的切片,而在要轉換的結構體上的字段可以是各種類型。這里就是gocsv包中的一個特點:可以將字段中的非string類型轉換成string類型,最終寫入到csv文件中。

6、可自定義類型轉換器??梢酝ㄟ^實現(xiàn)TypeMarshaller接口或TypeUnMarshaller接口對自定義類型的內(nèi)容按對應的格式輸出成csv內(nèi)容。

7、可自定義CSV的Reader/Writer來覆蓋默認參數(shù)。比如csv格式的內(nèi)容默認使用逗號分隔內(nèi)容。通過該功能我們可以指定使用其他分隔符的csv內(nèi)容。比如使用"|"或";"等。

這里需要注意的是 將csv文件的內(nèi)容一定是解析到結構體類型的切片或數(shù)組中。同樣,也只有是結構體類型的切片或數(shù)組才能直接寫入到csv文件中。

以上,就是今天我們要分享的工具包,更多關于Go CSV包工具的資料請關注腳本之家其它相關文章!

相關文章

  • Golang?sync.Once實現(xiàn)單例模式的方法詳解

    Golang?sync.Once實現(xiàn)單例模式的方法詳解

    Go?語言的?sync?包提供了一系列同步原語,其中?sync.Once?就是其中之一。本文將深入探討?sync.Once?的實現(xiàn)原理和使用方法,幫助大家更好地理解和應用?sync.Once,需要的可以參考一下
    2023-05-05
  • Go語言類型內(nèi)嵌和結構體內(nèi)嵌的具體使用

    Go語言類型內(nèi)嵌和結構體內(nèi)嵌的具體使用

    本文主要介紹了Go語言類型內(nèi)嵌和結構體內(nèi)嵌的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • go nil處理如何正確返回nil的error

    go nil處理如何正確返回nil的error

    這篇文章主要為大家介紹了go中的nil處理,如何正確返回nil的error實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • 基于Go語言簡單實現(xiàn)事件管理器

    基于Go語言簡單實現(xiàn)事件管理器

    在編程中,事件管理器是一種常見的工具,用于通過通知來觸發(fā)操作,本文將介紹一個簡單的Go事件管理器的實現(xiàn),并通過異步改進提高其性能,感興趣的可以了解下
    2023-11-11
  • 淺析golang如何在多線程中避免CPU指令重排

    淺析golang如何在多線程中避免CPU指令重排

    這篇文章主要為大家詳細介紹了golang在多線程中避免CPU指令重排的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-03-03
  • Go中的Timer 和 Ticker詳解

    Go中的Timer 和 Ticker詳解

    在日常開發(fā)中,我們可能會遇到需要延遲執(zhí)行或周期性地執(zhí)行一些任務,這個時候就需要用到 Go 語言中的定時器,本文將會對這兩種定時器類型進行介紹,感興趣的朋友一起看看吧
    2024-07-07
  • Golang?HTTP編程的源碼解析詳解

    Golang?HTTP編程的源碼解析詳解

    這篇文章主要為大家詳細介紹了Golang中的HTTP編程以及源碼解析,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的可以了解一下
    2023-02-02
  • Golang使用反射的動態(tài)方法調(diào)用詳解

    Golang使用反射的動態(tài)方法調(diào)用詳解

    Go是一種靜態(tài)類型的語言,提供了大量的安全性和性能。這篇文章主要和大家介紹一下Golang使用反射的動態(tài)方法調(diào)用,感興趣的小伙伴可以了解一下
    2023-03-03
  • Go?的入口函數(shù)和包初始化的使用

    Go?的入口函數(shù)和包初始化的使用

    本文主要介紹了Go?的入口函數(shù)和包初始化的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • Go語言單例模式詳解

    Go語言單例模式詳解

    本文主要介紹了Go語言單例模式詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03

最新評論