go語言基礎語法:異常處理,文字檔案處理,JSON處理,檔案操作
阿新 • • 發佈:2018-12-17
一、異常處理
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)二進位制檔案,記事本開啟,是亂碼
記憶體掉電,程式結束,記憶體中的內容消失
檔案存放在磁碟,掉電或程式結束,檔案還是存在