1. 程式人生 > >go語言基礎語法:異常處理,文字檔案處理,JSON處理,檔案操作

go語言基礎語法:異常處理,文字檔案處理,JSON處理,檔案操作

一、異常處理

1.err介面的使用

err1 := fmt.Errorf("%s", "this is normal error")
fmt.Println("err1=", err1)

err2 := errors.New("this is normal error,too")
fmt.Println("err2=", err2)

2.介面的應用

func MyDiv(a, b int) (result int, err error) {
	err = nil
	if b == 0 {
		err = errors.New("分母不能為0")
		return
	} else {
		result = a / b
	}
	return
}
func main() {
	result, err := MyDiv(10, 0)
	if err != nil {
		fmt.Println("err=", err)
	} else {
		fmt.Println("result=", result)
	}
}

3.顯式呼叫panic函式

func testa() {
	fmt.Println("aaaaaaaaaa")
}
func testb() {
	//fmt.Println("bbbbbbbbbbbb")
	//顯示呼叫panic函式,導致程式中斷
	panic("this is a panic test")
}
func testc() {
	fmt.Println("ccccccccccccccc")
}
func main() {
	testa()
	testb()
	testc()
}

4.陣列越界導致panic

func testa() {
	fmt.Println("aaaaaaaaa")
}
func testb(x int) {
	var a [10]int
	a[x] = 111
//當x為20的時候就會導致陣列越界,就會產生一個panic,導致程式崩潰
}
func testc() {
	fmt.Println("ccccccccc")
}
func main() {
	testa()
	testb(20)
	testc()
}

5.recover的使用

func testa() {
	fmt.Println("aaaaaaaaaa")
}
func testb(x int) {
//設定recover
	defer func() {
//recover()就可以打印出panic的錯誤資訊
		if err := recover(); err != nil {//產生了panic異常
			fmt.Println(err)
		}
	}()//匿名函式用()呼叫
	var a [10]int
	a[x] = 111
}
func testc() {
	fmt.Println("cccccccccccc")
}
func main() {
	testa()
	testb(20)
	testc()
}

二、文字檔案處理

1.字串操作

//檢視“hellogo”是否包含“hello”,包含返回true,否則返回false
fmt.Println(strings.Contains("hellogo", "hello"))//true
fmt.Println(strings.Contains("hello", "abc"))//false
//join組合
s := []string{"abc", "hello", "mike", "go"}
buf := strings.Join(s, "@")//用@把切片元素連線起來
fmt.Println("buf=", buf)
//index,查詢子串的位置
fmt.Println(strings.Index("abcdhello", "hello"))
fmt.Println(strings.Index("abcd", "go"))//不包含的返回-1
//repeat重複顯示
buf = strings.Repeat("go", 3)
fmt.Println("buf=", buf)
//split拆分,以指定分隔符拆分,存到切片中
buf = "[email protected]@[email protected]"
s2 := strings.Split(buf, "@")
fmt.Println("s2=", s2)
//trim去掉字串兩端的指定字元,存到字串裡
buf = strings.Trim("     are u ok?      ", " ")
fmt.Println("buf=", buf)
//fields,去掉字串空格,把元素放到切片中
s3 := strings.Fields("     are u ok?       ")
fmt.Println("s3=", s3)

2.字串轉換

標頭檔案"strconv"

//轉換為字串後追加到位元組陣列
slice := make([]byte, 0, 1024)
slice = strconv.AppendBool(slice, true)
//第二個數為要追加的數,第三個為指定10進位制方式追加
slice = strconv.AppendInt(slice, 1234, 10)
slice = strconv.AppendQuote(slice, "abcdhello")
fmt.Println("slice=", string(slice))
//其他型別轉換為字串型別
var str string
str = strconv.FormatBool(false)
fmt.Println("str=", str)
//'f'指列印格式,以小數方式,-1指小數點位數(緊縮模式),64以float64位處理
str = strconv.FormatFloat(3.14, 'f', -1, 64)
fmt.Println("str=", str)
//整型轉字串,常用
str = strconv.Itoa(666)
fmt.Println("str=", str)
//字串轉其它型別
var flag bool
var err error
//字串轉布林型別
flag, err = strconv.ParseBool("true1")
if err == nil {
	fmt.Println("flag=", flag)
} else {
	fmt.Println("err=", err)
}
//字串轉整型
a, _ := strconv.Atoi("567")
fmt.Println("a=", a)

3.正則表示式

標頭檔案"regexp"

buf := "abc azc a7c aac 888 a9c tac"
//1.解釋規則,它會解析這個正則表示式,如果成功就返回解析器
reg1 := regexp.MustCompile(`a[\d]c`)
if reg1 == nil {//解析失敗,reg1=nil
	fmt.Println("err=")
	return
}
//2.根據規則提取關鍵資訊
result1 := reg1.FindAllStringSubmatch(buf, -1)//-1是匹配所有的
fmt.Println("result=", result1)

buf := "83.14 567 abc 1.23 7. 9.0 asfg 6.78 7.9"
//解析正則表示式,+匹配前一個字元的1次或多次
reg := regexp.MustCompile(`\d+\.\d+`)
if reg == nil {
	fmt.Println("MustCompile err")
	return
}
//提取關鍵資訊
result := reg.FindAllStringSubmatch(buf, -1)
fmt.Println("result=", result)

buf := `<html lang="zh-CN">
<head>
	<title>Go語言標準庫文件中文版 | Go語言中文網 | Golang中文社群 | Golang中國</title>
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
	<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
	<meta charset="utf-8">
	<link rel="shortcut icon" href="/static/img/go.ico">
	<link rel="apple-touch-icon" type="image/png" href="/static/img/logo2.png">
	<meta name="author" content="polaris <[email protected]>">
	<meta name="keywords" content="中文, 文件, 標準庫, Go語言,Golang,Go社群,Go中文社群,Golang中文社群,Go語言社群,Go語言學習,學習Go語言,Go語言學習園地,Golang 中國,Golang中國,Golang China, Go語言論壇, Go語言中文網">
	<meta name="description" content="Go語言文件中文版,Go語言中文網,中國 Golang 社群,Go語言學習園地,致力於構建完善的 Golang 中文社群,Go語言愛好者的學習家園。分享 Go 語言知識,交流使用經驗">
</head>
	<div>哈哈</div>
	<div>嘿嘿
	你在嗎
	不在
	</div>
	<div>吼吼</div>
	<div>測試</div>
<frameset cols="15,85">
	<frame src="/static/pkgdoc/i.html">
	<frame name="main" src="/static/pkgdoc/main.html" tppabs="main.html" >
	<noframes>
	</noframes>
</frameset>
</html>`
reg := regexp.MustCompile(`<div>(?s:(.*?))</div>`)
if reg == nil {
	fmt.Println("MustCompile err")
	return
}
result := reg.FindAllStringSubmatch(buf, -1)
for _, text := range result {
	fmt.Println("text[1]=", text[1])//text[0]帶<></>
}

三、JSON處理

1.通過結構體生成json

標頭檔案“encoding/json”

//成員變數名首字母必須大寫
type IT struct {
	Company string
	Subject []string
	IsOk    bool
	Price   float64
}

func main() {
//定義一個結構體變數,同時初始化
	s := IT{"itcast", []string{"Go", "C++", "Python", "Test"}, true, 666.6}
//編碼,根據內容生成json文字
    //json.Marshal(s)為非格式化編碼
	buf, err := json.MarshalIndent(s, "", "	")//格式化編碼
	if err != nil {
		fmt.Println("err=", err)
		return
	}
	fmt.Println("buf=", string(buf))
}

2.通過map生成json

//建立一個Map
m := make(map[string]interface{}, 4)
m["company"] = "itcast"
m["subjects"] = []string{"Go", "C++", "Python", "Test"}
m["isok"] = true
m["price"] = 666.6
//編碼成json
result, err := json.MarshalIndent(m, "", "	")//格式化編碼
if err != nil {
	fmt.Println("err=", err)
	return
}
fmt.Println("result=", string(result))

3.json解析到結構體

type IT struct {
	Company  string   `json:"company"`//二次編碼
	Subjects []string `json:"subjects"`
	IsOk     bool     `json:"isok"`
	Price    float64  `json:"price"`
}

func main() {
	jsonBuf := `
	{
		"company":"itcast",
		"subjects":[
			"Go",
			"C++",
			"Python",
			"Test"
		],
		"isok":true,
		"price":666.666
	}`
	var tmp IT//定義一個結構體變數
	err := json.Unmarshal([]byte(jsonBuf), &tmp)//第二個引數要傳地址
	if err != nil {
		fmt.Println("err=", err)
		return
	}
	fmt.Printf("tmp=%+v\n", tmp)
//也實現部分結構體轉換
	type IT2 struct {
		Subject []string `json:"subjects"`
	}
	var tmp2 IT2
	err = json.Unmarshal([]byte(jsonBuf), &tmp2)
	if err != nil {
		fmt.Println("err=", err)
		return
	}
	fmt.Printf("tmp2=%+v\n", tmp2)
}

4.json解析到map

jsonBuf := `
{
	"company":"itcast",
	"subjects":[
		"Go",
		"C++",
		"Python",
		"Test"
	],
	"isok":true,
	"price":666.6
}`
m := make(map[string]interface{}, 4)
err := json.Unmarshal([]byte(jsonBuf), &m)
if err != nil {
	fmt.Println("err=", err)
	return
}	
fmt.Printf("m=%+v\n", m)
//str=string(m["company"])//err,無法直接轉換
//通過型別斷言來轉換
var str string
for key, value := range m {
	switch data := value.(type) {
	case string:
		str = data
		fmt.Printf("map[%s]的值型別為string,value=%s\n", key, str)
	case bool:
		fmt.Printf("map[%s]的值型別為bool,value=%v\n", key, data)
	case float64:
		fmt.Printf("map[%s]的值型別為float64,value=%v\n", key, data)
	case []interface{}:
		fmt.Printf("map[%s]的值型別為[]string,value=%v\n", key, data)
	}
}

四、檔案操作

1.裝置檔案的使用

標頭檔案"os"

//os.Stdout.Close()關閉後,無法輸出
fmt.Println("are u ready?")//往標準輸出裝置(螢幕)寫內容
//標準裝置檔案(os.Stdout),預設開啟,使用者可直接使用
os.Stdout.WriteString("are u ready?\n")
//os.Stdin.Close()關閉後就不能輸入了
var a int
fmt.Println("請輸入a:")
fmt.Scan(&a)//從標準輸入裝置中讀取內容,放在a中
fmt.Println("a=", a)

2.檔案的讀寫

標頭檔案"io","os","bufio","fmt"

func WriteFile(path string) {
//開啟檔案,新建檔案
	f, err := os.Create(path)
	if err != nil {
		fmt.Println("err=", err)
		return
	}
	defer f.Close()//使用完畢,關閉檔案
	var buf string
	for i := 0; i < 10; i++ {
//i=%d\n,這個字串儲存在buf中
		buf = fmt.Sprintf("i=%d\n", i)
		n, err := f.WriteString(buf)
		if err != nil {
			fmt.Println("err=", err)
		}
		fmt.Println("n=", n)
	}
}
func main(){
    path:="./demo.txt"
    WriteFile(path)
}

func ReadFile(path string) {
//開啟檔案
	f, err := os.Open(path)
	if err != nil {
		fmt.Println("err=", err)
		return
	}
	defer f.Close()//關閉檔案
	buf := make([]byte, 1024*2)//2k大小
//n代表從檔案讀取內容的長度
	n, err1 := f.Read(buf)
	if err1 != nil && err1 != io.EOF {//檔案錯處並且沒有到檔案結尾
		fmt.Println("err1=", err1)
		return
	}
	fmt.Println("buf=", string(buf[:n]))
}
func main(){
    path="./demo.txt"
    ReadFile(path)
}

//每次讀取一行
func ReadFileLine(path string) {
//開啟檔案
	f, err := os.Open(path)
	if err != nil {
		fmt.Println("err=", err)
		return
	}
	defer f.Close()//關閉檔案
//新建一個緩衝區,把內容先放在緩衝區
	r := bufio.NewReader(f)
	for {//遇到\n就停止,但是\n也被讀進來了
		buf, err1 := r.ReadBytes('\n')
		if err1 != nil {
			if err1 == io.EOF {//檔案結束,跳出迴圈,也就是讀完了
				break
			}
			fmt.Println("err1=", err1)
		}
		fmt.Printf("buf=#%s\n", string(buf))
	}
}
func main() {
	path := "./demo.txt"
	ReadFileLine(path)
}

3.拷貝檔案

list := os.Args//獲取命令列引數
if len(list) != 3 {
	fmt.Println("usage:xxx srcFile dstFile")
	return
}
srcFileName := list[1]
dstFileName := list[2]
if srcFileName == dstFileName {
	fmt.Println("原始檔和目的檔案不能同名")
	return
}
//以只讀方式開啟檔案
sF, err1 := os.Open(srcFileName)
if err1 != nil {
	fmt.Println("err1=", err1)
	return
}
//建立目的檔案
dF, err2 := os.Create(dstFileName)
if err2 != nil {
	fmt.Println("err2=", err2)
	return
}
//操作完畢要關閉檔案
defer sF.Close()
defer dF.Close()
//核心:從原始檔讀取內容,往目的檔案寫,讀多少寫多少
buf := make([]byte, 4*1024)//4k緩衝區
for {
	n, err3 := sF.Read(buf)
	if err3 != nil {
		if err3 == io.EOF {//檔案讀到末尾是迴圈的結束條件
			break
		}
		fmt.Println("err3=", err3)
	}
	dF.Write(buf[:n])//讀多少,寫多少
}

裝置檔案:

       螢幕(標準輸出裝置)fmt.println往標準輸出裝置寫內容

       鍵盤(標準輸入檔案)fmt.Scan從標準輸入裝置讀取內容

磁碟檔案,放在儲存裝置上的檔案

       1)文字檔案,以記事本開啟,不是亂碼

        2)二進位制檔案,記事本開啟,是亂碼

記憶體掉電,程式結束,記憶體中的內容消失

檔案存放在磁碟,掉電或程式結束,檔案還是存在