一、接口
定义
接口定义了一个对象的行为规范,制定以规范并不实现,具体的对象需要实现规范的细节
//接口定义
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)
}