Go语言的异常处理:
通过err处理异常:非致命错误,实则变量和参数都是string类型。
err1:=fmt.Errorf("%s","this is normal err1")
package main
import"errors"
func main(){
err2:=errors.New("this is normal err2")
}
err接口的应用:除法函数
func div (a,b int) (result int, err error){
if b==0{
ree=reeors.New("分母不能为0")
}else {
result = a/b
}
return
}
func main(){
result,err:=div(10,0)
if err!=nil{
fmt.Println(err)
}else{
fmt.Println(result)
}
}
通过panic处理异常:程序致命错误。
显式调用panic导致程序中断:
func test(){
panic("this is a panic test") //自动打印
}
panic函数的应用:数组越界错误。
func test(x int){
var a [10]int
a[x]=1 //数组越界则会产生panic错误
}
通过recover处理错误:必须要放在defer后面使用,不会导致程序崩溃,可以打印错误信息。
func test(x int){
defer func(){ //匿名函数判断错误
if err := recover(); err!=nil{
fmt.Println(err)
}
}()
var a [10]int
a[x]=1
文本和文件的处理:
字符串处理:
字符串长度处理:需要导入包strings
import "strings"
func Contains (s, substr string) bool
//功能:字符串s中是否包含substr,返回bool值
func Join (a []string, sep string) string
//功能:字符串链接,把slice a通过sep链接起来
func Index (s, sep string) int
//功能:在字符串s中查找sep所在位置,返回位置值,找不到返回-1
func Repeat (s string, count int) string
//功能:重复s字符串count次,最后返回重复的字符串
func Replace (s, old, new string, n int) string
//功能:在s字符串中,把old字符串替换为new字符串,n表示替换的次数,小宇0表示全部替换
func Split (s,sep string) []string
//功能:把s字符串按照sep分割,返回slice
func Trim (s string, cutset string) string
//功能:在s字符串的头部和尾部取出cutset指定的字符串
func Fields (s sting) []string
//功能:取出s字符串的空格符,并且按照空格分割返回slice
字符串的转换:需要导入包strconv
Append系列函数将整数等转换为字符串后,添加到现有的字节数组中。
str:=make([]byte, 0, 100)
str=strconv.AppendInt(str, 4567, 10) //整数转换常用,10代表以十进制追加
str=strconv.AppendBool(str, false)
str=strconv.AppendQuote(str, "abc")
str=strconv.AppendQuoteRune(str, "单")
Format系列函数把其他类型的转换为字符串。
a:=strconv.FormatBool(false)
b:=strconv.FormatInt(1234,10)
c:=strconv.FormatUint(1234,10)
d:=strconv.Itoa(1234)
Parse系列函数把字符串转换为其他类型。
flag, err:=strconv.ParseBool("true") //err返回报错信息
aint, err:=strconv.Atoi("567") //整型转换
正则表达式:模式匹配和文本操纵,比strings包来进行搜索,替换,解析更为强大,但效率较低,不够清晰可读性差。
需要导入包“regexp”,实现了正则表达式的搜索。正则表达式采用RE2语法(出了\c,\C),和Perl、Python等语言的正则基本一致。
可以通过以下网址查找详细信息:
http://code.google.com/p/re2/wiki/Syntax
https://studygolang.com/pkgdoc
提取字符串中想相应字段:
package main
import "fmt"
import "regexp"
func main(){
buf := `abcbaxcaacc` //可以通过反引号``也可以通过双引号"",反引号代表原生字符串
//解析规则,它会解析正则表达式,如果成功返回解释器*Regexp
reg1 := regexp.MustCompile(`a.c`)
if reg==nil{ //解析失败
fmt.Println("err")
return
}
//根据规则提取关键信息
result := reg1.FindAlllStringSubmatch(buf, -1) //匹配个数,-1匹配全部
}
buf := `ab9cbaxcb3cc`
reg1 := regexp.MustCompile(`b[0-9]c`) //或用`b\dc`
if reg==nil{
fmt.Println("err")
return
}
result := reg1.FindAlllStringSubmatch(buf, -1)
提取字符串中的所有小数:
buf := `43.14 5. 7. .8 46.3 3.14 25.22`
reg1 := regexp.MustCompile(`\d+\.\d+`) //+匹配前一个字符的1次或多次
if reg==nil{
fmt.Println("err")
return
}
//result := reg1.FindAlllString(buf, -1)
result := reg1.FindAlllStringSubmatch(buf, -1) //详细打印
正则表达式读取网页:
buf := `/*网页源代码*/`
reg1 := regexp.MustCompile(`<div>(.*)</div>`) //取标题
reg2 := regexp.MustCompile(`<div>(?s:(.*))</div>`) //匹配换行
reg2 := regexp.MustCompile(`<div>(?s:(.*?))</div>`) //重复匹配,越少越好
if reg==nil{
fmt.Println("err")
return
}
//result := reg1.FindAlllString(buf, -1)
result := reg1.FindAlllStringSubmatch(buf, -1) //详细打印
//迭代器过滤<></>
for _,text := range result {
//fmt.Println("text[0]") //带<></>
fmt.Println("text[1]") //不带<></>
json处理:数据格式的交换文本,可前往www.json.cn进行格式检查。需要导入包:“encoding/json”
生成(编码)json文本信息:
通过结构体生成文本:
package main
import "encoding/json"
import "fmt"
type IT struct { //成员变量名字一定要大写
Company string
Subjects []string
IsOk bool
Price sloat64
}
func main(){
s:=IT{"itcast",[]string{"Go","C++","Python","Test"},true,666.666} //定义初始化结构体
buf, err := json.Marshal(s) //编码,根据内容生成json文本
//buf, err := json.MarshalIndent(s, "", " ") //格式化编码,格式更加准确.""空字符." "tap
if err != nil{
fmt.Println(err)
return
}
fmt.Println(string(buf))
}
二次编码:
type IT struct {
Company string `json:"company"` //首字母小写输出
Subjects []string `json:"-"` //不输出到屏幕
IsOk bool `json:",string"` //转换成字符串输出
Price sloat64
}
通过map生成文本:不同类型运用空接口
m:=make(map[string]interface{}, 4) //创建map
m["company"] = "itcast"
m["subjects"] = []string{"Go","C++","Python","Test"}
m["isok"] = true
m["price"] = 666.666
result, err := json.MarshalIndent(s, "", " ") //格式化编码,格式更加准确.""空字符." "tap
if err != nil{
fmt.Println(err)
return
}
fmt.Println(string(result))
编码反过程:解码
json解析到结构体:
package main
import "encoding/json"
import "fmt"
type IT struct {
Company string `json:"company"`
Subjects []string `json:"subjects"`
IsOk bool `json:"isok"`
Price sloat64 `json:"price"`
}
func main(){
jsonBuf := `/*json文本*/`
var tmp IT
err := json.Unmarshal([]byte(jsonBuf), &tmp)
if err != nil{
fmt.Println(err)
return
}
fmt.Printf("%+v", tmp)
}
如果对单一的json文段解码:可重新定义一个结构体并只包含单一文段。
json解析到map:解析简单但判断类型更为复杂
m:=make(map[string]interface{}, 4)
err := json.Unmarshal([]byte(jsonBuf), &m)
if err != nil{
fmt.Println(err)
return
}
fmt.Printf("%+v", m)
//取字段内容,只能通过类型断言,较为复杂。
for key, value := range m{
switch data:=value.(type){
case string:
fmt.Printf("map[%s]的值类型为string,值为:%s\n",key,data)
case bool:
fmt.Printf("map[%s]的值类型为bool,值为:%v\n",key,data)
case float64:
fmt.Printf("map[%s]的值类型为float64,值为:%f\n",key,data)
case []string:
fmt.Printf("map[%s]的值类型为[]string,值为:%v\n",key,data)
case []interface{}:
fmt.Printf("map[%s]的值类型为[]nterface{},值为:%v\n",key,data)
}
}
文件分类:
设备文件:
1.屏幕(标准输出设备)fmt.Println() 向标准输出设备输出内容
2.键盘(标准输入设备)fmt.Scan() 从标准输入设备读取内容
磁盘文件:在磁盘上存储的文件:
1.文本文件:可以直接通过记事本看到正常内容。
2.二进制文件:不可以直接以记事本形式打开,打开后只能看到乱码。
问什么需要文件储存内容:内存掉电之后数据就会丢失,程序结束内存中的内容也会消失。磁盘文件在程序结束后,文件内容仍然存在。
os.Stdout.Close() //关闭标准设备文件输出,默认打开
fmt.Println() //无法使用
os.Studout.WriteString() //无法使用
os.Stdin.Close() //关闭标准设备输入,默认打开
fmt.Scan() //无法使用
文件操作:需要导入包“os”
import "os"
文件的创建:
func Create(name string) (file *File, err Error)
//根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的
func NewFile(fd unitptr, name string) *File
//根据文件描述符创建相应的文件,返回一个文件对象
文件的打开:
func Open(name string) (file *File, err Error)
//该方法打开一个名称为name的文件,但是是制度方式,内部实现其调用了OpenFile
func OpenFile(name string, flag int, perm uint32) (file *File, err Error)
//打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限
文件的写入:
func (file *File) Write(b []byte) (n int, err Error)
//写入byte类型的信息到文件
func (file *File) WriteAt(b []byte, off int64) (n int, err Error)
//在指定位置开始写入byte类型的信息
func (file *File) WriteString(s string) (ret int, err Error)
//写入string信息到文件
文件的读取:
func (dile *File) Read(b []byte) (n int, err Error)
//读取数据到b中
func (dile *File) ReadAt(b []byte, off int64) (n int, err Error)
//从off开始读取数据到b中
文件的删除:
func Remove(name string) Error
//调用改函数就可以删除文件名为name的文件
文件的创建以及写入实例:
package main
import "fmt"
import "os"
func WriteFile(path string) {
f, err := os.Create(path) //新建文件
if err != nil {
fmt.Println(err)
return
}
defer f.Close() //文件关闭
buf := fmt.Sprintf("输入文本")
n, errx := f.WriteString(buf)
if errx != nil {
fmt.Println(err)
return
}
fmt.Println(n) //文件长度
}
func main() {
path := "./demo.txt" //文件路径:程序当前目录下的demo
WriteFile(path)
}
文件的读取实例:
package main
import "fmt"
import "os"
import "io"
func ReadFile(path string) {
f, err := os.Open(path) //打开文件
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
buf := make([]byte, 1024*2) //2kB大小
n, errx := f.Read(buf)
if errx != nil && errx != io.EOF { //文件未到结尾出错
fmt.Println(err)
return
}
fmt.Println(string(buf[:n]))
}
func main() {
path := "./demo.txt"
ReadFile(path)
}
借助bufio实现按行读取内容:
package main
import "fmt"
import "os"
import "io"
import "bufio"
func ReadFileLine(path string) {
f, err := os.Open(path)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
r := bufio.NewReader(f) //新建一个缓存区暂存内容
for {
//以换行分割,'\n'换行也会一并被读入
buf, errx := r.ReadBytes('\n') //以\n分割并标记
if errx != nil {
if errx == io.EOF { //文件读取完毕
fmt.Println(string(buf))
break
}
fmt.Println(err)
}
fmt.Println(string(buf))
}
}
func main() {
path := "./demo.txt"
ReadFileLine(path)
}
文件案例:拷贝文件:
package main
import "fmt"
import "os"
import "io"
func main() {
list := os.Args //获取命令行参数
if len(list) != 3 {
fmt.Println("err:文件参数不足3")
return
}
srcFileName := list[1]
dstFileName := list[2]
if srcFileName == dstFileName {
fmt.Println("起始文件与目标文件不能同名")
return
}
sF, err1 := os.Open(srcFileName) //只读方式打开源文件
if err1 != nil {
fmt.Println("err:", err1)
return
}
dF, err2 := os.Create(dstFileName) //新建目的文件
if err1 != nil {
fmt.Println("err:", err2)
return
}
defer sF.Close() //关闭文件
defer dF.Close()
//核心处理,从源文件读取内容写入目标文件
buf := make([]byte, 4*1024) //4kB大小临时缓冲区
for {
n, err := sF.Read(buf) //从源文件读取内容
if err != nil {
if err == io.EOF { //文件读取完毕
dF.Write(buf[:n])
break
}
fmt.Println("err:", err)
}
dF.Write(buf[:n]) //写入目标文件
}
}
通过命令行:go run name.go file1.type file2.type完成拷贝。