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

Go語言七篇入門教程五文件及包

 更新時間:2021年11月09日 16:48:18   作者:小生凡一  
本章節(jié)主要介紹go語言的文件處理與包管理,本文是Go語言七篇入門教程系列篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步

1. 文件處理

1.1 JSON文件

什么是json?

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。
也是在web開發(fā)中的前后端交互的格式。

encoding/json是官方提供的標準 json, 實現 RFC 7159 中定義的 JSON 編碼和解碼。
使用的時候需要預定義 struct,原理是通過 reflection 和 interface 來完成工作。

常用的接口:

func Marshal(v interface{}) ([]byte, error) 	  // 生成 JSON
func Unmarshal(data []byte, v interface{}) error  // 解析 JSON 到 struct

1.1.1 已知JSON結構

先看例子

package main
import (
	"encoding/json"
	"fmt"
)
type Person struct {
	Name string
	Age   string
}
type PersonSlice struct {
	Persons []Person
}
func main() {
	var s PersonSlice
	str := `{"persons":[{"Name":"FanOne","Age":"17"},{"Name":"FanOne2","Age":"18"},{"Name":"FanOne3","Age":"19"}]}`
	_ = json.Unmarshal([]byte(str), &s) 
	// Golang中提供軟件包"encoding/json"可以直接用來處理JSON文件,此包中解析JSON的函數為Unmarshal
	// 使用此函數可以將JSON文件解析到結構體中
	fmt.Println(s.Persons)//[{FanOne 17} {FanOne2 18} {FanOne3 19}]
	for _,item:=range s.Persons{
		fmt.Println("Name",item.Name,"Age",item.Age)
		//Name FanOne Age 17
		//Name FanOne2 Age 18
		//Name FanOne3 Age 19
	}
}

上例中,首先定義了與json數據對應的結構體,數組對應slice,字段名對應JSON里面的KEY,

在解析的時候,如何將json數據與struct字段相匹配呢?例如JSON的key是Name,那么怎么找對應的字段呢?

  • 首先查找tag含有Name的可導出的struct字段(首字母大寫)
  • 其次查找字段名是Name的導出字段
  • 最后查找類似NAME或者NaMe這樣的除了首字母之外其他大小寫不敏感的導出字段

其中需要注意一點:能夠被賦值的字段必須是可導出字段(即首字母大寫)。因為只有首字母大寫才能被外面應用,同時JSON解析的時候只會解析能找得到的字段,找不到的字段會被忽略。

這樣的一個好處是:當你接收到一個很大的JSON數據結構而你卻只想獲取其中的部分數據的時候,你只需將你想要的數據對應的字段名大寫,即可輕松解決這個問題。

雖然沒有python直接.json那么方便,但是也還是算不錯的。

1.1.2 未知JSON結構

眾所周知,在Go語言中,interface{}可以用來存儲任意數據類型的對象,此數據結構正好用于存儲解析的未知結構的json數據的結果。

JSON包中采用map[string]interface{}[]interface{}結構來存儲任意的JSON對象和數組。

Go類型和JSON類型的對應關系如下:

bool 代表 JSON booleans,

float64 代表 JSON numbers,

string 代表 JSON strings,

nil 代表 JSON null.

b := []byte(`{
		"Name": "FanOne",
		"School": ["FZU", "XCZX", "UUUU", "GuaguaSong", "HanTuo",
		"City", "FuZhou"],
		"Major": "BigData",
		"IsPublished": true,
		"Price": 9.99,
		"Sales": 1000000
}`)
var r interface{}
err := json.Unmarshal(b, &r)

在上述代碼中,r 被定義為一個空接口。
json.Unmarshal()函數將一個 JSON 對象解碼
到空接口 r 中,最終 r 將會是一個鍵值對的map[string]interface{}結構:

	map[string]interface{}{ 
		"Name": "FanOne",
		"School": ["FZU", "XCZX", "UUUU", "GuaguaSong", "HanTuo",
		"City", "FuZhou"],
		"Major": "BigData",
		"IsPublished": true,
		"Price": 9.99,
		"Sales": 1000000
	}

要訪問解碼后的數據結構,需要先判斷目標結構是否為預期的數據類型:

gobook, ok := r.(map[string]interface{})

然后,我們可以通過 for 循環(huán)搭配 range 語句一一訪問解碼后的目標數據:

	if ok {
		for k, v := range gobook
		{
			switch v2 := v.(type)
			{
			case string:
				fmt.Println(k, "is string", v2)
			case int:
				fmt.Println(k, "is int", v2)
			case bool:
				fmt.Println(k, "is bool", v2)
			case []interface{}:
				fmt.Println(k, "is an array:")
				for i, iv := range v2 {
					fmt.Println(i, iv)
				}
			default:
				fmt.Println(k, "is another type not handle yet")
			}
		}
	}

雖然有些煩瑣,但的確是一種解碼未知結構的 JSON 數據的安全方式。

1.1.3 Encoder & Decoder

Go 內建的 encoding/json 包還提供 Decoder 和 Encoder 兩個類型,用于支持 JSON 數據的流式讀寫,并提供 NewDecoder()和 NewEncoder()兩個函數來便于具體實現:

func NewDecoder(r io.Reader) *Decoder
func NewEncoder(w io.Writer) *Encoder
func main() {
	dec := json.NewDecoder(os.Stdin)
	enc := json.NewEncoder(os.Stdout)
	for {
		var v map[string]interface{}
		if err := dec.Decode(&v); err != nil{
			log.Println(err)
			return
		}
		for k := range v {
			if k != "Name" {
				v[k] = nil,false
			}
		}
		if err := enc.Encode(&v); err != nil{
			log.Println(err)
		}
	}
}

使用 Decoder 和 Encoder 對數據流進行處理可以應用得更為廣泛些,比如讀寫 HTTP 連接、WebSocket 或文件等,Go 的標準庫 net/rpc/jsonrpc 就是一個應用了 Decoder 和 Encoder的實際例子。

1.2 XML文件

XML 數據格式
對于如下的XML:

<Person>
    <FirstName>Fan</FirstName>
    <LastName>One</LastName>
</Person>

和 JSON 的方式一樣,XML 數據可以序列化為結構,或者從結構反序列化為 XML 數據;

encoding/xml包實現了一個簡單的 XML 解析器(SAX),用來解析 XML 數據內容。下面的例子說明如何使用解析器:

復制代碼
// xml.go
package main
import (
    "encoding/xml"
    "fmt"
    "strings"
)
var t, token xml.Token
var err error
func main() {
    input := "<Person><FirstName>Fan</FirstName><LastName>One</LastName></Person>"
    inputReader := strings.NewReader(input)
    p := xml.NewDecoder(inputReader)
    for t, err = p.Token(); err == nil; t, err = p.Token() {
        switch token := t.(type) {
        case xml.StartElement:
            name := token.Name.Local
            fmt.Printf("Token name: %s\n", name)
            for _, attr := range token.Attr {
                attrName := attr.Name.Local
                attrValue := attr.Value
                fmt.Printf("An attribute is: %s %s\n", attrName, attrValue)
            }
        case xml.EndElement:
            fmt.Println("End of token")
        case xml.CharData:
            content := string([]byte(token))
            fmt.Printf("This is the content: %v\n", content)
            // ...
        default:
            // ...
        }
    }
}

輸出:

Token name: Person
Token name: FirstName
This is the content: Fan
End of token
Token name: LastName
This is the content: One
End of token
End of token

包中定義了若干XML 標簽類型:StartElement,Chardata(這是從開始標簽到結束標簽之間的實際文本)EndElement,Comment,Directive 或 ProcInst。

包中同樣定義了一個結構解析器:
NewParser 方法持有一個 io.Reader(這里具體類型是strings.NewReader)并生成一個解析器類型的對象。
還有一個 Token() 方法返回輸入流里的下一個 XML token。在輸入流的結尾處,會返回(nil,io.EOF)
XML 文本被循環(huán)處理直到 Token() 返回一個錯誤,因為已經到達文件尾部,再沒有內容可供處理了。
通過一個 type-switch 可以根據一些 XML 標簽進一步處理。Chardata中的內容只是一個 []byte,通過字符串轉換讓其變得可讀性強一些。

1.3 二進制文件

go語言可以在win下進行如下的設置將go程序build成二進制文件

請?zhí)砑訄D片描述

set CGO_ENABLED=0
set GOOS=linux
set GOARCH=amd64
go build main.go

1.4 zip文件

1.4.1 創(chuàng)建zip

Go語言提供了archive/zip包來處理zip壓縮文件

func createZip(filename string) {
	// 緩存壓縮文件內容
	buf := new(bytes.Buffer)
	// 創(chuàng)建zip
	writer := zip.NewWriter(buf)
	defer writer.Close()
	// 讀取文件內容
	content, _ := ioutil.ReadFile(filepath.Clean(filename))
	// 接收
	f, _ := writer.Create(filename)
	f.Write(content)
	filename = strings.TrimSuffix(filename, path.Ext(filename)) + ".zip"
	ioutil.WriteFile(filename, buf.Bytes(), 0644)
}

1.4.2 讀取zip文件

讀取zip文檔過程與創(chuàng)建zip文檔過程類似,需要解壓后的文檔目錄結構創(chuàng)建:

func readZip(filename string) {
      zipFile, err := zip.OpenReader(filename)  // 打開zip文件
		if err != nil {
			panic(err.Error())
		}
		defer zipFile.Close()
		for _, f := range zipFile.File {  // 循環(huán)讀取zip中的內容
			info := f.FileInfo()
			if info.IsDir() { 
				err = os.MkdirAll(f.Name, os.ModePerm)
				if err != nil {
					panic(err.Error())
				}
				continue
			}
			srcFile, err := f.Open()  // 打開文件
			if err != nil {
				panic(err.Error())
			}
			defer srcFile.Close()
			newFile, err := os.Create(f.Name)
			if err != nil {
				panic(err.Error())
			}
			defer newFile.Close()
			io.Copy(newFile, srcFile)
		}
}

2. 包管理

2.1 包路徑

每一個包都通過一個唯一的字符串進行標識,它稱為導入路徑,他們用在import聲明當中。
對于準備共享或公開的包需要全局唯一。當然也要保證沒有循環(huán)的導包,循環(huán)的導包會引起報錯,而這也就涉及到了程序項目的整體層次結構上了,這點以后再說。

2.2 包聲明

在每一個Go源文件的路徑的最后一段,需要進行聲明。主要目的是當該包被其他包引入的時候作為默認的標識符。

例如在引入 "fmt"之后,可以訪問到它的成員,fmt.Println(),可以注意到這個P是大寫的,說明了,要大寫才能跨包引用。

當我們導用的包的名字沒有在文件中引用的時候,就會有一個編譯錯誤。我們可以使用_來代表

表示導入的內容為空白標識符。

在這里插入圖片描述

以上就是Go語言七篇入門教程五文件及包的詳細內容,更多關于Go語言文件及包的資料請關注腳本之家其它相關文章!

如何學習Go

如果你是小白,你可以這樣學習Go語言~

七篇入門Go語言

第一篇:Go簡介初識

第二篇:程序結構&&數據類型的介紹

第三篇:函數方法接口的介紹

第四篇:通道與Goroutine的并發(fā)編程

第六篇:網絡編程

第七篇:GC垃圾回收三色標記

相關文章

  • Golang實現支付寶沙箱支付的方法步驟

    Golang實現支付寶沙箱支付的方法步驟

    本文主要介紹了Golang實現支付寶沙箱支付的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • Go Time庫中時間和日期相關的操作方法整理

    Go Time庫中時間和日期相關的操作方法整理

    這篇文章主要為大家整理了Go語言中的time庫,包括時間、日期和時區(qū)等相關概念及使用方法,希望通過掌握這些知識,大家可以更好地處理時間、日期和時區(qū)相關的問題
    2023-08-08
  • Go到底能不能實現安全的雙檢鎖(推薦)

    Go到底能不能實現安全的雙檢鎖(推薦)

    這篇文章主要介紹了Go到底能不能實現安全的雙檢鎖,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • Golang中使用Swagger生成API文檔的流程步驟

    Golang中使用Swagger生成API文檔的流程步驟

    Swagger 是一款強大的 API 文檔生成工具,可以幫助開發(fā)者輕松創(chuàng)建、管理和展示 RESTful API 文檔,在本文中,我們將介紹如何在 Golang 項目中使用 Swagger 來生成 API 文檔,文中有相關的代碼示例供大家參考,需要的朋友可以參考下
    2024-07-07
  • Go語言開發(fā)環(huán)境搭建與初探(Windows平臺下)

    Go語言開發(fā)環(huán)境搭建與初探(Windows平臺下)

    Go是Google開發(fā)的一種編譯型,並發(fā)型,并具有垃圾回收功能的編程語言,可能很多人想學習go語言,那么首先就要了解go語言的環(huán)境配置方法
    2014-10-10
  • Go并發(fā)控制Channel使用場景分析

    Go并發(fā)控制Channel使用場景分析

    使用channel來控制子協(xié)程的優(yōu)點是實現簡單,缺點是當需要大量創(chuàng)建協(xié)程時就需要有相同數量的channel,而且對于子協(xié)程繼續(xù)派生出來的協(xié)程不方便控制
    2021-07-07
  • Go語言Swagger實現為項目生成 API 文檔

    Go語言Swagger實現為項目生成 API 文檔

    Swagger 是一個基于 OpenAPI 規(guī)范設計的工具,用于為 RESTful API 生成交互式文檔,下面小編就來介紹一下如何在 Go 項目中集成 Swagger,特別是結合 Gin 框架生成 API 文檔
    2025-03-03
  • 創(chuàng)建第一個Go語言程序Hello,Go!

    創(chuàng)建第一個Go語言程序Hello,Go!

    這篇文章主要介紹了創(chuàng)建第一個Go語言程序Hello,Go!本文詳細的給出項目創(chuàng)建、代碼編寫的過程,同時講解了GOPATH、Go install等內容,需要的朋友可以參考下
    2014-10-10
  • Golang變量直接初始化的方法詳解

    Golang變量直接初始化的方法詳解

    在 Go 語言中,我們常用的數據結構有在Go語言中,你可以初始化不同的數據結構,例如數組、切片、結構體、指針、map等,本文將給大家介紹一下Golang變量直接初始化的方法,需要的朋友可以參考下
    2023-08-08
  • Go基礎教程之環(huán)境搭建及常用命令

    Go基礎教程之環(huán)境搭建及常用命令

    這篇文章主要介紹了Go基礎教程之環(huán)境搭建及常用命令的相關資料,包括Go語言簡介、環(huán)境配置、包管理工具GoModules以及常用命令的全面介紹,需要的朋友可以參考下
    2025-03-03

最新評論

古交市| 泰州市| 伊吾县| 达拉特旗| 辽中县| 彭山县| 广宗县| 隆化县| 甘泉县| 合山市| 涡阳县| 蕉岭县| 武川县| 樟树市| 平和县| 固安县| 梧州市| 浙江省| 弥勒县| 石首市| 洪江市| 青州市| 深州市| 长子县| 崇仁县| 和龙市| 石台县| 海林市| 碌曲县| 乌拉特后旗| 乐业县| 姜堰市| 城市| 兴山县| 山阴县| 宜阳县| 石景山区| 石门县| 犍为县| 海兴县| 安新县|