zoukankan      html  css  js  c++  java
  • 第四章 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("
    
    ")
        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)
    }
    

      

  • 相关阅读:
    思维导图 第八章 项目质量管理
    思维导图 第七章 项目成本管理
    redis安装与配置
    思维导图 第六章 项目进度管理
    思维导图 第五章 项目范围管理
    Linux下用户-组权限配置
    意灵魔法馆首页的初步设计
    try catch自定义异常类的使用
    使用freemarker时,生成的html出现乱码
    乱码问题
  • 原文地址:https://www.cnblogs.com/parallel-Y/p/11420757.html
Copyright © 2011-2022 走看看