Day_05
01.error接口的使用
package main import "fmt" import "errors" func main() { //var err1 error = fmt.Errorf("%s","This is normal err") err1 := fmt.Errorf("%s", "This is normal err1") fmt.Println("err1 = ", err1) err2 := errors.New("This is normal err2") fmt.Println("err2 = ", err2) }
02.error接口的应用
package main import "fmt" import "errors" func MyDiv(a, b int) (result int, err error) { err = nil if b == 0 { err = errors.New("分母不能为0,你这个笨蛋") } else { result = a / b } return } func main() { result, err := MyDiv(10, 0) if err != nil { fmt.Println("err = ", err) } else { fmt.Println("result = ", result) } }
03.显式调用panic函数
/* 在通常情况下,向程序使用方报告错误状态的方式可以是返回一个额外的error类型值。 但是,当遇到不可恢复的错误状态的时候,如数组访问越界、空指针引用等,这些运行时错误 会引起panic异常,这时,上述错误处理方式显然就不适合了。反过来讲,在一般情况下, 我们不应该通过调用panic函数来报告普通的错误,而应该只把它作为报告致命错误的一种方式。 当某些不应该发生的场景发生时,我们就应该调用panic。 一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine(线程),当中被延迟的函数(defer机制)。 随后,程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。 不是所有的panic异常都来自运行时,直接调用内置的panic函数也会引发panic异常 panic函数接受任何值作为参数。 */ package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaaaaaaaaaa") } func testb() { //fmt.Println("bbbbbbbbbbbbbbbbbbbbb") //显式调用panic函数,导致程序中断 panic("This is a panic test") } func testc() { fmt.Println("ccccccccccccccccccccc") } func main() { testa() testb() testc() }
04.数组越界导致panic
package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaaaaaaaaaa") } func testb(x int) { var a [10]int a[x] = 111 //当x为20的时候,导致数组越界,产生一个panic,导致程序崩溃 } func testc() { fmt.Println("ccccccccccccccccccccc") } func main() { testa() testb(20) testc() }
05.recover的使用
package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaaaaaaaaaa") } func testb(x int) { //设置recover defer func() { //recover() //可以打印panic的错误信息 //fmt.Println(recover()) if err := recover(); err != nil { // 产生了panic异常 fmt.Println(err) } }() //别忘了(),调用此匿名函数 var a [10]int a[x] = 111 //当x为20的时候,导致数组越界,产生一个panic,导致程序崩溃 } func testc() { fmt.Println("ccccccccccccccccccccc") } func main() { testa() testb(20) testc() }
06.字符串操作
package main import ( "fmt" "strings" ) func main() { //"hellogo"中是否包含"hello",包含返回true,不包含返回false fmt.Println(strings.Contains("hellogo", "hello")) //Join组合,以@作为分隔符将s这个切片转换为字符串 s := []string{"abc", "hello", "mike", "go"} buf := strings.Join(s, "@") fmt.Println("buf =", buf) //Index,查找子串的位置,存在返回下标,不存在返回-1 fmt.Println(strings.Index("abcdhello", "hello")) fmt.Println(strings.Index("abcdhello", "go")) //Repeat,重复10次Go buf = strings.Repeat("Go", 10) fmt.Println("buf=", buf) //Split 以指定的分隔符拆分字符串,返回一个切片 buf = "hello@abc@go@Jason" s2 := strings.Split(buf, "@") fmt.Println("s2 =", s2) //Trim去掉两头的字符 buf = strings.Trim(" are u ok? ", " ") //去掉2头空格 fmt.Printf("buf = #%s#\n", buf) //去掉空格,把元素放入切片中 s3 := strings.Fields(" are u ok? ") for i, data := range s3 { fmt.Println(i, ", ", data) } }
07.字符串转换
package main import ( "fmt" "strconv" ) func main() { //转换为字符串后追加到字节数组 slice := make([]byte, 0, 1024) slice = strconv.AppendBool(slice, true) //第二个数为要追加的数,第3个为指定10进制方式追加 slice = strconv.AppendInt(slice, 1234, 10) slice = strconv.AppendQuote(slice, "abcgohello") fmt.Println("slice = ", string(slice)) //转换string后再打印 //其他类型转换为字符串 var str string str = strconv.FormatBool(false) //'f'指打印格式,以小数方式,-1指小数点位数(紧缩模式),64以float64处理 str = strconv.FormatFloat(3.14, 'f', -1, 64) //整型转字符串,常用 str = strconv.Itoa(66666) fmt.Printf("str = %s,type = %T\n", str, str) //字符串转其他类型 var flag bool var err error flag, err = strconv.ParseBool("true") if err == nil { fmt.Println("flag = ", flag) } else { fmt.Println("err = ", err) } //把字符串转换为整型 a, _ := strconv.Atoi("567") fmt.Printf("a = %d,type = %T\n", a, a) }
08.正则表达式1
package main import ( "fmt" "regexp" ) func main() { buf := "abc azc a7c aac 888 a9c tac" // 1)解释规则,它会解析正则表达式,如果成功返回解释器 reg1 := regexp.MustCompile(`afdsafsac`) //reg1 := regexp.MustCompile(`a[0-9]c`) //reg1 := regexp.MustCompile(`a\dc`) if reg1 == nil { //说明解释失败,返回nil fmt.Println("解释失败了,没有找到匹配项") return } // 2)根据规则提取关键信息,-1是匹配所有 result1 := reg1.FindAllStringSubmatch(buf, -1) fmt.Println("result1 = ", result1) }
09.正则表达式2
package main import ( "fmt" "regexp" ) func main() { buf := "34.14 567 agsdg 1.23 7. 8. 99 1sdljgl 6.66121 7.8" //解析正则表达式,+匹配前一个字符1次或多次 reg := regexp.MustCompile(`\d+\.\d+`) if reg == nil { fmt.Println("MustCompile Err") return } //提取关键信息 result := reg.FindAllStringSubmatch(buf, -1) fmt.Println("result = ", result) }
10.正则表达式3
package main import ( "fmt" "regexp" ) func main() { //`` 原生字符串 buf := ` <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <meta content=IE=7 http-equiv=X-UA-Compatible> <meta http-equiv="Cache-Control" content="no-transform" /> <meta http-equiv="Cache-Control" content="no-siteapp" /> <meta name="applicable-device"content="pc"> <title>SW问问搜搜问问 - 这里只有问题和答案</title> <meta name="keywords" content="搜搜问问,搜搜,问问,sosowenwen,搜搜问答,搜搜知道,soso问问" /> <meta name="description" content="搜搜问问可找到你知道的答案,同时,我们也期待您在搜搜问问平台上回答网友提出的问题,及时贡献您的知识,与他人分享您的经验" /> <link rel=stylesheet type=text/css href="/templets/vip_skin/images/base.css" media=screen /> <link rel=stylesheet type=text/css href="/templets/vip_skin/images/home.css" media=screen /> </head> <div>哈哈哈</div> <div>测试 法师打发的撒 发 范德萨发生大 rewwwe 切勿让 </div> <div>百事可乐</div> <div>可口可乐</div> <div>Adidas</div> <div>Nike</div> </html> ` //解析正则表达式,+匹配前一个字符1次或多次 //reg := regexp.MustCompile(`<div>(.*)</div>`) reg := regexp.MustCompile(`<div>(?s:(.*?))</div>`) if reg == nil { fmt.Println("MustCompile Err") return } //提取关键信息 result := reg.FindAllStringSubmatch(buf, -1) //fmt.Println("result = ", result) //过滤<></> for _, text := range result { //fmt.Println("text[0] = ", text[0]) //带<></> fmt.Println("text[1] = ", text[1]) //不带<></> } }
11.通过结构体生成JSON
package main import ( "encoding/json" "fmt" ) /* { "company":"ITCAST", "subjects":[ "Go", "C++", "Java", "Python" ], "isok":true, "Price":666.666 } */ //成员变量名首字母必须大写 //type IT struct { // Company string // Subjects []string // Isok bool // Price float64 //} type IT struct { Company string `json:"-"` //此字段不会输出到屏幕 Subjects []string `json:"subjects"` //二次编码,将大写转换为小写 Isok bool `json:",string"` //将bool转换为string Price float64 `json:",string"` //将浮点数转换为string } func main() { //定义一个结构体变量,同时初始化 s := IT{"itcast", []string{"Go", "C++", "Java", "Python"}, true, 666.666} //编码,根据内容生成json文本 //{"Company":"itcast","Subjects":["Go","C++","Java","Python"],"Isok":true,"Price":666.666} // buf, err := json.Marshal(s) buf, err := json.MarshalIndent(s, "", " ") //格式化编码 if err != nil { fmt.Println("err = ", err) return } fmt.Println("buf = ", string(buf)) }
12.通过map生成JSON
package main import ( "encoding/json" "fmt" ) func main() { //创建一个map m := make(map[string]interface{}, 4) m["company"] = "ITCAST" m["subjects"] = []string{"Go", "C++", "Java", "Python"} m["isok"] = true m["price"] = 888.888 //编码成JSON result, err := json.MarshalIndent(m, "", " ") // 格式化编码 if err != nil { fmt.Println("err = ", err) return } fmt.Println("result = ", string(result)) }
13.JSON解析成结构体
package main import ( "encoding/json" "fmt" ) // 因为jsonbuf的键都为小写,而结构体的首字母必须大写,所有在``内手动将结构体强行改为小写 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++", "Java", "Python" ], "isok":true, "Price":666.666 }` var tmp IT //定义一个结构体变量 err := json.Unmarshal([]byte(jsonBuf), &tmp) // 第二个参数要地址传递 if err != nil { fmt.Println("err=", err) return } // fmt.Println("tmp = ",tmp) fmt.Printf("tmp = %+v\n", tmp) //以下是单独取subjects这一个子类的情况,而非全部 type IT2 struct { Subjects []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) }
14.JSON解析成map
package main import ( "encoding/json" "fmt" ) func main() { jsonBuf := ` { "company":"ITCAST", "subjects":[ "Go", "C++", "Java", "Python" ], "isok":true, "Price":666.666 }` // 创建一个map 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) // var str string // str = string(m["company"]) // err,无法转换 // fmt.Println("str = ", str) var str string //类型断言,值,它是value类型 for key, value := range m { //fmt.Printf("%v ===============>%v\n", key, value) 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 = %f\n", key, data) case []string: fmt.Printf("map[%s]的值类型为[]string,value = %v\n", key, data) case []interface{}: fmt.Printf("map[%s]的值类型为[]interface,value = %v\n", key, data) } } }
15.设备文件的使用
package main import ( "fmt" "os" ) func main() { // os.Stdout.Close() //关闭后,无法输出 fmt.Println("are u ok?") //往标准输出设备(屏幕)写内容 // 标准设备文件,默认已经打开,用户可以直接使用 os.Stdout.WriteString("Hello,I AM stdout......") os.Stdin.Close() //关闭后,无法输入 var a int fmt.Println("请输入a: ") fmt.Scan(&a) //从标准输入设备中读取内容,放在a中 fmt.Println("a = ", a) }
16.文件的读写
package main import ( "fmt" "io" "os" ) 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 = 1\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 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" WriteFile(path) ReadFile(path) }