第四章 Go语言开发应用

 一、接口

  定义

  接口定义了一个对象的行为规范,制定以规范并不实现,具体的对象需要实现规范的细节

//接口定义
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("\n\n")
    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\n",a,a)    //int 100
    var c string = "hi"
    a = c
    fmt.Printf("%T %v\n",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\n",a,a)    //map[string]int map[abc:100 aaa:30]
}

func Descrtribe(a interface{}){
    fmt.Printf("type = %T %v\n",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\n",v)
    case int:
        fmt.Printf("a is int,value:%v\n", v)
    case float32:
        fmt.Printf("a is float32,value:%v\n", v)
    default:
        fmt.Println("not support type\n")
    }
}
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\n",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\n",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\n")
        qv.Elem().SetFloat(6.8)    //Elem()相当于指针赋值中的*
    }
}
func test() {
    var x float64 =  3.4
    reflect_set_valur(&x)
    fmt.Printf("x value is %v\n",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\n")
    case reflect.Float32:
        fmt.Println("s is Float32\n")
    case reflect.Struct:
        fmt.Printf("s is struct\n")
        fmt.Printf("field num of s is %d\n",v.NumField())    //获取结构体的参数个数用NumField()
        for i:= 0;i<v.NumField();i++ {
            field := v.Field(i)
            fmt.Printf("name:%s type:%v value:%v\n",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\n",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\n",s)
{
func test(){
    var s Student
    s.SetName("xxx")
    v := reflect.ValueOf(&s)
    t := v.Type()
    fmt.Printf("struct student have %d methods\n",t.NumMethod())
    for i := 0;i<NumMethod();i++ {
        method := t.Method(i)
        fmt.Printf("struct %d method,name:%s type :%v\n",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\n",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\n",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\n",field0.Tag.Get("json"))
  fmt.Printf("tag db=%s\n",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\n",err)
        return
    }
    defer inputFile.Close()
}

//读取文件
func main() {
    file,err := os.Open("文件名")    //只读的方式打开
    if err != nil {
        fmt.Printf("open file err:%v\n",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\n",err)
        return
    }
    defer inputFile.Close()
    reader := bufio.NewReader(file)
    for {
        line,err := reader.ReadString("\n")    //按行读
        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\n",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\n",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\n",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\n",dstName,err)
        return
    }
    defer dst.Close()
    return io.Copy(dst.src)
}

//cat命令实现
func cat (r *bufio.Reader) {
    for {
        buf,err := r.ReadByter('\n')
        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\n",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\n",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\n",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\n",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\n",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)
}

  

转载于:https://www.cnblogs.com/parallel-Y/p/11420757.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值