一、接口
定义
接口定义了一个对象的行为规范,制定以规范并不实现,具体的对象需要实现规范的细节
//接口定义 type 接口名 interface { //定义一个接口 Talk() Eat() int //返回int型 Run() }
接口的实现
一个对象只要包含接口中的方法,那么就是实现了这个接口,接口类型的变量可以保存具体类型的实例
type Animal interface{ Talk() Eat() Name() string } type Dog struct{ } func (d Dog) Talk(){ fmt.Println("汪汪") } func (d Dog) Eat(){ fmt.Println("吃骨头") } func (d Dog) Name() string{ fmt.Println("旺财") return "旺财" } func test(){ var b Dog var a Animal a = b a.Name() a,Eat() a.Talk() }
接口调用sort排序
type Student struct { Name string Id string Age int } type StudentArray []Student func (p StudentArray) Len() int { return len(p) } func (p StudentArray) Less(i, j int) bool { return p[i].Name > p[j].Name } func (p StudentArray) Swap(i,j int) { p[i],p[j] = p[j],p[i] } func test(){ var stus StudentArray for i := 0;i<10;i++{ stu := Student{ Name : fmt.Sprintf("stu%d",rand.Intn(100)), Id : fmt.Sprintf("110%d",rand.Intn()), Age : randIntn(100), } stus = append(stus,stu) } for _,v := range stus{ fmt.Println(v) } fmt.Println(" ") sort.Sort(stus) for _,v := range stus{ fmt.Println(v) } }
空接口
空接口没有定义任何方法,所以任何类型都能实现空接口
func test(){ var a interface{} var b int = 100 a = b fmt.Printlf(%T %v ",a,a) //int 100 var c string = "hi" a = c fmt.Printf("%T %v ",a,a) //string hi var d map[string]int = make(map[string]int,10) d["abc"] = 100 d["aaa"] = 30 a = d fmt.Printf("%T %v ",a,a) //map[string]int map[abc:100 aaa:30] } func Descrtribe(a interface{}){ fmt.Printf("type = %T %v ",a,a) } type Student struct{ Name string Sex int } func test2(){ a := 99 describe(a) //type=int 99 b := "hello" describe(b) //type = string hello var stu Student = Student{ Name:"user01", Sex:1, } describe(stu) //type = main.Student {user01 1} }
类型断言
获取接口类型里面存储的具体值
//OK语句判断 func describe(a interface{}) { s,ok := a.(int) if ok { //使用ok语法,防止传入类型错误报错 fmt.Println(s) return } str,ok := a.(string) if ok{ fmt.Println(str) return } f,ok := a.(float32) if ok { fmt.Println(f) return } fmt.Println("输入错误") return } func test(){ var a int = 100 describe(a) var b string = "hi" describe(b) } //sitch-type语句判断 func testSwitch(a interface{}) { switch v := a.(type) { case stirng:L fmt.Printf("a is string,value:%v ",v) case int: fmt.Printf("a is int,value:%v ", v) case float32: fmt.Printf("a is float32,value:%v ", v) default: fmt.Println("not support type ") } } func test2(){ var a int = 100 testSwitch(a) var b string = "Parallel" testSAwitch(b) }
指针接收和值接收区别
值类型实现的接口指针类型变量可以存入,指针类型实现的接口值类型变量不能存入
//同一兑现够可以实现多个接口 type Animal interface{ Talk() } type Bu interface{ Bu() } type Dog struct{ } func (d Dog) Talk(){ fmt.Println("汪汪") } func (d Dog) Bu(){ fmt.Println(*狗是哺乳动物") } func test(){ var d Dog var a Animal a = d a.Talk() var b Bu b = d b.Bu() }
接口实现链表
type LinkNode struct{ data interface{} next *LinkNode } type Link struct { head *LinkNode tail *LikNode } func (p *Link) InsertHead(data interface{}) { node := &LinkNode{ data : data, next : nil, } if p.taiil == nil && p.head == nil{ p.tail = node p.head = node return } node.next = p.head p.head = node } func (p *Link) InsertTail(data interfdace{}) { node := &LinkNode{ data : data, next : nil, } if p.tail == nil && p.head{ p.tail = node p.head = node reutrn } p.tail.next = node p.tail = node } func (p *Link) Trans(){ q := p.head if q != nil { fmt.Println(q.data) q = q.next } } func main(){ var intLink Link for i := 0;i<10;i++{ intLink.InsertHead(i) intLink.InsertTail(i) } intLink.Trans() }
接口嵌套
type Animal interface { Eat() } type Describle interface { Describled() } type AdvanceAnimal interface { Animal Describle } type Dog struct { } func (d Dog) Eat() { fmt.Println("狗吃屎") } func (d Dog) Describled() { fmt.Println("狗") } func test() { var d Dog var a AdvanceAnimal a = d a.Eat() a.Describled() }
二、反射
定义
空接口可以存储任何类型的变量,在运行时动态的获取一个变量的类型信息和值信息就是反射
//获取类型信息:reflect.TypeOf import { "fmt" "reflect" } func reflect_example(a interface{}) { t := reflect.TypeOf(a) fmt.Printf("type of a is:%v ",t) } func test(){ var x float32 = 3.4 reflect_example(x) } //获取变量的类型:Type.Kind() import ( "fmt" "reflect" } func reflect_example(a interface{}) { t := reflect.TypeOf(a) fmt.Printf("type of a is :%v ",t) k := t.Kind() switch k { case reflect.Int64: fmt.Println("a is int64") case reflect.String: fmt.Printf("a is string") } } func test() { var x float32 = 3.4 reflect_example(x) } //获取值信息:reflect.ValueOf func reflect_value(a interface{}) { v := reflect.ValueOf(a) k := v.Kind() switch k { case reflect.Int64: fmt.Printf("a is int64,value is :%d",v.int()) case reflect.Float64: fmt.Printf("a is Float64,value is:%f",v.Float()) } } func test() { var x float64 = 3.4 reflect_value(x) } //反射设置变量值:value.Elem().SetFloat() func reflect_set_value(a interface{}) { v := reflect.ValueOf(a) k := v.Kind() switch k { case reflect.Int64: v.SetInt(100) fmt.Printf("a is int64,value is :%d",v.Int()) case reflect.Float64: v.SetFloat(6.8) fmt.Printf("a is Float64,value is:%f",v.Float()) case reflect.Ptr: fmt.Printf("set a to 6.8 ") qv.Elem().SetFloat(6.8) //Elem()相当于指针赋值中的* } } func test() { var x float64 = 3.4 reflect_set_valur(&x) fmt.Printf("x value is %v ",x) } /* 注: var *p int = new(int) *p = 100 //正常指针赋值,设置的值需要和变量类型匹配 */
结构体反射
获取和设置结构体字段的信息
//获取结构体信息 type Student struct { Name string Sex int Age int } func test(){ var s Student v := reflect.ValueOf(s) t := v.Type() kind := t.Kind() switch kind { case reflect.Int64: fmt.Printf("s is int64 ") case reflect.Float32: fmt.Println("s is Float32 ") case reflect.Struct: fmt.Printf("s is struct ") fmt.Printf("field num of s is %d ",v.NumField()) //获取结构体的参数个数用NumField() for i:= 0;i<v.NumField();i++ { field := v.Field(i) fmt.Printf("name:%s type:%v value:%v ",t.Field(i).Name,field.Type(),field.Interface()) } default: fmt.Println("default") } } //设置结构体相关字段的值 type Student struct { Name stirng Sex int Age int } func test(){ var s Student v := reflect.ValueOf(&s) v.Elem().Field(0).SetString("stu01") v.Elem().FieldByName("Sex").SetInt(2) v.Elem().FieldByName("Age").SetInt(15) fmt.Printf("s:%#v ",s) }
获取和调用结构体方法中的信息
//获取结构体的方法信息 type Student struct { Name string Sex int Age int Score float32 } func (s *Student) SetName(name string) { s.Name = name } func (s *Student) Print(){ fmt.printf("%#v ",s) { func test(){ var s Student s.SetName("xxx") v := reflect.ValueOf(&s) t := v.Type() fmt.Printf("struct student have %d methods ",t.NumMethod()) for i := 0;i<NumMethod();i++ { method := t.Method(i) fmt.Printf("struct %d method,name:%s type :%v ",i,method.Name,method.Type) } } //调用结构体中的方法 type Student struct { Name string Sex int Age int Score float 32 } func (s *Student) SetName(name string) { s.Name = name } func (s *Student) Print() { fmt.Printf("%#v ",s) } func test2() { var s Student s.SetName("xxx") v := reflect.ValueOf(&s) m1 := v.MethodByName("Print") var args []reflect.Value m1.Call(args) //调用有参数结构体的方法 m2 := v.MethodByName("SetName") var args2 []reflect.Value name := "stu01" nameVal := reflect.ValueOf(name) args2 = append(args2,nameVal) m2.Call(args2) m1.Call(args) }
//获取结构体中tag信息
type Studenrr struct {
Name string `json:"name" db:"name2"`
Sex int
Age int
Score float32
}
func (s *Student) SetName(name string) {
s.Name = name
}
func (s *Student) Print() {
fmt.Printf("%#v ",s)
}
func test(){
var s Student
s.SetName("xxx")
v := reflect.ValueOf(&s)
t := v.Type()
field0 := t.Elem().Field(0)
fmt.Printf("tag json=%s ",field0.Tag.Get("json"))
fmt.Printf("tag db=%s ",field0.Tag.Get("db"))
}
反射总结和应用场景
总结:在运行时动态获取一个变量的类型和值信息
应用场景:
1 序列化和反序列化,比如json、protobuf等各种数据协议
2 各种数据库的ORM、如果gorm、sqlx等数据库中间件
3 配置文件解析相关的库,比如yaml、ini等
三、文件操作
文件打开和读取
定义:文件分为文本文件和二进制文件两种,存取方式有随机存取和顺序存放
//打开文件 func main() { inputFile,err := os.Open("文件名") //只读的方式打开 if err != nil { fmt.Printf("open file err :%v ",err) return } defer inputFile.Close() } //读取文件 func main() { file,err := os.Open("文件名") //只读的方式打开 if err != nil { fmt.Printf("open file err:%v ",err) return } defer inputFille.Close() var content []byte var buf [128]byte for { n,err := file.Read(buf[:]) if err == io.EOF{ break } if err != nil { fmt.Println("read file:",err) return } content = append(content,buf[:n]...) } fmt.Println(string(content)) } //bufio读取文件 func test() { inputFile,err := os.Open("路径.文件名") //只读的方式打开 if err != nil { fmt.Printf("open file err:%v ",err) return } defer inputFile.Close() reader := bufio.NewReader(file) for { line,err := reader.ReadString(" ") //按行读 if err == io.EOF{ brea=k } if err != nil { fmt.Println("read file failed,err:",err) return } fmt.Println(line) } } //注bufio原理:读取和写入的时候先进入缓冲区,可以提升效率,但是缓冲区无法保存,断电消失 //io/ioutil读取整个文件 func test2(){ content,err := ioutil.ReadFile("./file.go") if err != nil { fmt.Println("read file failed,err:",err) return } fmt.Println(string(content)) } //读取压缩文件 func test3() { inputFile,err := os.Open("文件名.gz”) //只读的方式打开 if err != nil { fmt.Println("open file err:%v ",err) return } defer inputFile.Close() reader,err := gzip.NewReader(file) if err != nil { fmt.Println("gzip new reader failed,err",err) return } var countent []byte var buf [128]byte for { n,err := reader.reader.Read(buf[:]) if err == io.EOF { break } if err != nil { fmt.Println("read file:",err) return } content = append(content,buf[:n]...) } fmt.Println(string[content)) }
文件写入
公式:os.OpenFile("文件路径.文件名",参数2,参数3)
参数2:文件打开模式:os.O_WRONLY(只写) os.O_CREATE(创建) os.O_RDONLY(只读)
os.O_RDWR(读写) os.O_TRUNC(清空) os.O_APPEND(追加) 多个模式之间用逗号隔开
参数3:权限控制(windows下无效) r——004 w——002 x——001
//文件写入 func test() { file,err := os.OpenFile("./test.txt",os.O_CREATE|os.O_TRUNC|os.O_WRONLY,0666) //文件不存在则创建文件,清空文件,写文件 if err != nil { fmt.Println("open file failed,err:",err) return } defer file.Close() str := "hello world" file.Write([]byte(str) file.WriteString(str) } //bufio方式写入文件 func test2(){ file,err := os.OpenFile("./test.txt",os.O_CREATE4|os.O_TRUNC|os.O_WRONLY,0666) if err != nil{ fmt.Println("open file failed,err:",err) return } defer file.Close() writer := bufio.NewWriter(file) //使用bufio写文件 for i := 0;i < 10;i++ { //写入10行 writer.WriteString("hello world"), } write.Flush() //写入的内容还在内存中,此命令让内容上传到文件中 } //io/ioutil写到整个文件 func test3() { str := "hello world" err := ioutil.WriteFile("./test.txt",p[byte(str),0755) if err != nil { fmt.Println("write file failed,err:',err) return } }
copy和cat命令实现
//文件拷贝 func test() { _,err := CopyFile("target.txt","source.txt") if err !=nil{ fmt.Printf("copy file failed,err:%v ",err) return } fmt.Println("Copy done!") } func CopyFile(dstName,srcName string) (written int64,err error) { src,err := os.Open(srcName) if err != nil { fmt.Printf("Open source file %s failed,err:%v ",srcName,err) return } defer src.Close() dst,err := os.OpenFile(dstName,os.O_WRONLY|os.CREATE,0644) if err != nil { fmt.Printf("open dest file %s failed,err:%v ",dstName,err) return } defer dst.Close() return io.Copy(dst.src) } //cat命令实现 func cat (r *bufio.Reader) { for { buf,err := r.ReadByter(' ') if err == io.EOF { break } fmt.Printf(os.Stdout,"%s",buf) } } func test() { flag.Parse() if flag.Narg() == 0 { cat(bufio.NewReader(os.Stdin)) } for i := 0;i< flag.Narg();i++ { f,err := os.Open(flag.Arg(i)) if err != nil { fmt.Fprintf(os.Srder,"%s:error reading from %s:%s ",os.Args[0],flag.Arg(i),err.Error() continue } cat(bufio.NewReader(f)) } }
defer详解
原理:
//案例 func test() int{ x ;= 5 defer func() { x +=1 }() return 5 //6 } func test2() (x int) { defer func() { x += 1 }() return 5 //6 } func test3() (y int) { x := 5 defer func() { x += 1 }() return x //5 } func test4() (x int) { defer func(x int) //此时传入的是x的副本 x+=1 }(x) return 5 }
四、Json数据协议
定义:
序列化:json.Marshal(data interface{})
import "encoding/json" //导入包 //结构体 type User struct{ UserName string `json:"username"` //json数据显示为小写的tag NickName string Age int Birthday string Sex string Email string Phone string } func test(){ user1 := &User{ Username :"user01", NickName:"上课", Age:10, Birthday:"2008", Sex:"男", Email:"123@qq.com", Phone:"110", } data,err := json.Marshal(user1) if err != nil { fmt.Println("json marshal failed,err:",err) } fmt.Printf("%s ",string(data)) } //整型 func testInt() { var age = 100 data,err := json.Marshal(age) if err != nil{ fmt.Println("json.marshal failed,err:",err) return { fmt.Printf("%s ",string(data)_) } //map func testmao() { var m map[string]interface{} m = make(map[string]interface{}) m["username"] = "user01" m["age"] = 18 m["sex"] = "man" data,err := json.Marshal(m) if err != nil { fmt.Println("json marshal failed,err:",err) return } fmt.Printf("%s ",string(data)) } //切片 func testSlice() { var m map[string] interface{} var s []map[string]interface{} m = make(map[string]interface{}) m["username"] = "user1" m["age"] = 19 m["sex"] = "man" s = append(s,m) m = make(map[string]interface{}) m["username"] = "user02" m["age"] = 20 m["sex"] = "feman" s = append(s,m) data,err := json.Marshal(s) if err != nil{ fmt.Println("json marshal failed,err:"err) return } fmt.Printf("%S ",string(data)) }
反序列化:json.UnMarashal(data []byte,v interface{})
//结构体 type User struct { UserName string `json:"username"` //显示为小写 NickName string Age int Birthday string Sex string Email string Phone string } func teststruct() (ret string,err error) { user1 := &User{ UserName : "user01", NickName : "上课", Age : 10, Birthday : "2008", Sex : "男", Email : "123@qq.com", Phone : "110", } data,err := json.Marshal(user1) if err != nil { err = fmt.Error("json marshal failed,err:",err) return } ret = string(data) return } func main() { data,err := testStudent() if err != nil { fmt.Println("test,struct failed,",err) retuirn } fmt.Println(user1) } //map func testmap() (ret string,err error) { var m map[string] interface{} m = make(map[string]interface{}) m["username"] = "user1" m["age"] = 19 m["sex"] = "man" data,err := json.Marshal(m) if err != nil { err = fmt.Error("json.marshal failed,err:",err) return } ret = string(data) return } func test2() { datas,err := testmap() if err != nil{ fmt.Println("Unmarshal failed,"err") return } var m map[string]interface{} err = json.Unmarshal([]byte(data),&m) if err != nil{ fmt.Println("Unmarshal failed,"err) return } fmt.Println(m) }