最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go?CSV包實(shí)現(xiàn)結(jié)構(gòu)體和csv內(nèi)容互轉(zhuǎn)工具詳解

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

引言

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

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

gocsv小檔案

gocsv 小檔案
star1.5 kused by1.6k
contributors80作者gocarina
功能簡(jiǎn)介提供一個(gè)簡(jiǎn)單、高效地將csv內(nèi)容和結(jié)構(gòu)體進(jìn)行互轉(zhuǎn)的功能
項(xiàng)目地址github.com/gocarina/go…
相關(guān)知識(shí)reflect、結(jié)構(gòu)體tag

gocsv的基本功能

gocsv包的最基本的作用就是能夠方便的將csv內(nèi)容轉(zhuǎn)換到對(duì)應(yīng)的結(jié)構(gòu)體上,或者將結(jié)構(gòu)體的內(nèi)容快速的轉(zhuǎn)換成csv格式(包括寫入文件)。

gocsv.UnmarshalFile函數(shù):csv內(nèi)容轉(zhuǎn)成結(jié)構(gòu)體

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

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

然后從文件中讀取出內(nèi)容,并直接轉(zhuǎn)換到結(jié)構(gòu)體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ù):結(jié)構(gòu)體轉(zhuǎn)成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)
	}
}

自定義類型轉(zhuǎn)換器

gocsv包還可以給自定義的結(jié)構(gòu)體類型定義csv和結(jié)構(gòu)體的互轉(zhuǎn)函數(shù)。只要自定義的類型實(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
}

或者將結(jié)構(gòu)體轉(zhuǎn)換成csv字符串時(shí),需要實(shí)現(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
}

例如,我們定義了一個(gè)結(jié)構(gòu)體DateTime,里面有一個(gè)time.Time類型的屬性。并且DateTime類型實(shí)現(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學(xué)堂",
			Employed: DateTime{time.Now()},
		},
	}
	csvContent, _ := gocsv.MarshalString(client)
	fmt.Println("csv:", csvContent) //輸出內(nèi)容是 001,Go學(xué)堂,20231003
}

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

001,Go學(xué)堂,20231003

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

自定義CSV的Reader/Writer

在開頭處我們提到,csv文件中的分隔符默認(rèn)是逗號(hào)。但也可以是其他字符。這就要求我們?cè)谧x取或?qū)懭胫爸付ê脙?nèi)容的分隔號(hào)。那么就可以通過自定義的Reader/Writer來覆蓋默認(rèn)的Reader/Writer的選項(xiàng)。如下:

  • 指定讀取內(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)容是用 分割符 "|" 進(jìn)行分割的
gocsv.SetCSVWriter(func(out io.Writer) *gocsv.SafeCSVWriter {
	writer := csv.NewWriter(out)
    writer.Comma = '|'
    return gocsv.NewSafeCSVWriter(writer)
})

gocsv包的特點(diǎn)總結(jié)

1、結(jié)構(gòu)體切片和csv內(nèi)容互轉(zhuǎn)。能夠?qū)⒔Y(jié)構(gòu)體切片(或數(shù)組)直接輸出成csv內(nèi)容或輸出到文件。反之亦然。

2、csv標(biāo)簽。其轉(zhuǎn)換過程是通過結(jié)構(gòu)體上的“csv”標(biāo)簽進(jìn)行關(guān)聯(lián)的。

3、csv標(biāo)簽對(duì)應(yīng)csv內(nèi)容表頭。當(dāng)結(jié)構(gòu)體和csv格式互轉(zhuǎn)時(shí),結(jié)構(gòu)體中的csv標(biāo)簽對(duì)應(yīng)的就是csv表格的表頭,結(jié)構(gòu)體中的字段順序?qū)?yīng)的就是csv文件列的順序。

4、底層依然是使用標(biāo)準(zhǔn)庫中的csv。在寫入csv文件時(shí),底層實(shí)際上用的還是go標(biāo)準(zhǔn)庫中的encoding/csv/Writer結(jié)構(gòu)體的Write(row []string)方法。

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

6、可自定義類型轉(zhuǎn)換器。可以通過實(shí)現(xiàn)TypeMarshaller接口或TypeUnMarshaller接口對(duì)自定義類型的內(nèi)容按對(duì)應(yīng)的格式輸出成csv內(nèi)容。

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

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

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

相關(guān)文章

  • Go語言之使用pprof工具查找goroutine(協(xié)程)泄漏

    Go語言之使用pprof工具查找goroutine(協(xié)程)泄漏

    這篇文章主要介紹了Go語言之使用pprof工具查找goroutine(協(xié)程)泄漏,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Golang根據(jù)job數(shù)量動(dòng)態(tài)控制每秒?yún)f(xié)程的最大創(chuàng)建數(shù)量方法詳解

    Golang根據(jù)job數(shù)量動(dòng)態(tài)控制每秒?yún)f(xié)程的最大創(chuàng)建數(shù)量方法詳解

    這篇文章主要介紹了Golang根據(jù)job數(shù)量動(dòng)態(tài)控制每秒?yún)f(xié)程的最大創(chuàng)建數(shù)量方法
    2024-01-01
  • 詳解Golang中Channel的用法

    詳解Golang中Channel的用法

    如果說goroutine是Go語言程序的并發(fā)體的話,那么channels則是它們之間的通信機(jī)制。這篇文章主要介紹Golang中Channel的用法,需要的朋友可以參考下
    2020-11-11
  • Go語言使用組合的思想實(shí)現(xiàn)繼承

    Go語言使用組合的思想實(shí)現(xiàn)繼承

    這篇文章主要為大家詳細(xì)介紹了在 Go 里面如何使用組合的思想實(shí)現(xiàn)“繼承”,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語言有一定的幫助,需要的可以了解一下
    2022-12-12
  • 解析golang中的并發(fā)安全和鎖問題

    解析golang中的并發(fā)安全和鎖問題

    本文我們來學(xué)習(xí)一下golang中的并發(fā)安全和鎖問題,文章通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-11-11
  • GoLang中生成UUID唯一標(biāo)識(shí)的實(shí)現(xiàn)

    GoLang中生成UUID唯一標(biāo)識(shí)的實(shí)現(xiàn)

    這篇文章主要介紹了GoLang中生成UUID唯一標(biāo)識(shí)的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go語言常見錯(cuò)誤之a(chǎn)ny沒傳遞任何信息解決分析

    Go語言常見錯(cuò)誤之a(chǎn)ny沒傳遞任何信息解決分析

    Go語言,由于其高效強(qiáng)大的并行處理能力和優(yōu)雅簡(jiǎn)單的設(shè)計(jì)哲學(xué),一直以來都是編程世界的寵兒,然而,對(duì)于一些Go新手和甚至熟悉Go的程序員也可能會(huì)遇到一個(gè)常見的錯(cuò)誤:?any沒傳遞任何信息,那么,如何規(guī)避這個(gè)錯(cuò)誤,本文將揭示其中的秘密
    2024-01-01
  • Golang設(shè)計(jì)模式之外觀模式講解和代碼示例

    Golang設(shè)計(jì)模式之外觀模式講解和代碼示例

    外觀是一種結(jié)構(gòu)型設(shè)計(jì)模式, 能為復(fù)雜系統(tǒng)、 程序庫或框架提供一個(gè)簡(jiǎn)單 (但有限) 的接口,這篇文章就給大家詳細(xì)介紹一下Golang的外觀模式,文中有詳細(xì)的代碼示例,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-06-06
  • 一文詳細(xì)談?wù)凣oLang的panic和error

    一文詳細(xì)談?wù)凣oLang的panic和error

    說是初識(shí),并不是說第一次使用error和panic包,而是第一次特地去了解golang中的這兩個(gè)機(jī)制,下面這篇文章主要給大家介紹了關(guān)于如何通過一文詳細(xì)談?wù)凣oLang中panic和error的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • 一文帶你了解Go語言中的類型斷言和類型轉(zhuǎn)換

    一文帶你了解Go語言中的類型斷言和類型轉(zhuǎn)換

    在Go中,類型斷言和類型轉(zhuǎn)換是一個(gè)令人困惑的事情,他們似乎都在做同樣的事情。最明顯的不同點(diǎn)是他們具有不同的語法(variable.(type)?vs?type(variable)?)。本文我們就來深入研究一下二者的區(qū)別
    2022-09-09

最新評(píng)論

高要市| 清丰县| 永登县| 全椒县| 武鸣县| 射洪县| 涿鹿县| 长白| 唐山市| 奉化市| 肇州县| 通州区| 临西县| 乌恰县| 年辖:市辖区| 上思县| 治县。| 义马市| 娄烦县| 福泉市| 江门市| 兴城市| 余庆县| 汝南县| 疏勒县| 新干县| 秦安县| 洪江市| 临江市| 宜宾市| 宣城市| 伽师县| 仙游县| 蓝田县| 枞阳县| 剑川县| 大庆市| 洛阳市| 合山市| 拜城县| 高雄县|