• go语言,方法,接口,异常处理


    go语言·

      1,方法

      2,接口 

    //方法   其实方法就是一个函数
    /*
        基础知识:
            1.方法:对象绑定方法,类绑定方法
                特点:就是可以自动传值
            2,在Python中,写在类当中,没有加装饰器的,从严格意义说,如果类来调,就是一个函数,对象调,就是方法
                类来调,有几个参数就传几个参数,self要自己手动传
        go方法:
            //语法  (a Person)叫接受器称之为方法
            //func (a Person) getName()  {
            //}
            //方法是给对象用的,给结构体绑定方法
            //例如给Person结构体加一个打印名字的方法
    type  Person struct {
        name string
        age int
    }
    
    //语法  (a Person)叫接受器称之为方法
    //func (a Person) getName()  {
    //}
    //方法是给对象用的,给结构体绑定方法
    //例如给Person结构体加一个打印名字的方法
    func (a Person) printName()  {  //  printName()就是普通函数,有返回值就在后面加返回值类型
        fmt.Println(a.name)
    }
    
    //普通函数
    func printName(a Person)  {
        fmt.Println(a.name)
    }
    
    func (a *Person) changeName(name string){
        a.name=name
        fmt.Println(a)
    }
    func main() {
        //p:=Person{name:"lqz"}
        //p.printName()
        ////执行函数
        //printName(p)
        //为什么已经有函数了,还要有方法?
        // 方法有了,就相当于你拿到一个百宝箱,直接可以点拿到结构体中属性,面向对象的
        // 而函数需要一个个去传去取
        
        p:=&Person{name:"lqz"}
        p.changeName( "qqq")
        fmt.Println(p)
    
    
        //值接受器与指针类型接受器
        //值接受器相当于新copy一份过去,进行改的时候改的是copy过来的,不影响原来的
        //指针接受器是地址
        //func (a Person) printName() 即func (写值) printName(),在内部修改值,不会影响外部的值
        //func (a *Person) printName() 即func (指针) printName(name string) 在内部修改值,会影响外部的//什么时候用指针接受器,什么时候用值接受器
        // 是否改变外部值和拷贝结构体的代价
    }
    package main
    
    import "fmt"
    
    //匿名字段的方法  可以提升
    
    type Person1 struct {
        name string
        age int
        sex int
        Hobby  //匿名字段  不匿名不会提升
    }
    
    type Hobby struct {
        id int
        hobbyname string
    }
    
    func (h Hobby) printHobbyId()  { //绑定方法
        fmt.Println(h.id)
    }
    
    func (a Person1) printName()  {
        fmt.Println(a.name)
    }
    
    func (a *Person1) changeName(name string)  {
        a.name=name
        fmt.Println(a)
    }
    
    func main() {
        p:=Person1{name:"lqz",Hobby:Hobby{id:10}}
        //p.printHobbyId()
        //正常操作
        p.Hobby.printHobbyId()  //10
        //非正常操作,方法也提升了
        p.printHobbyId()   //10   用了面向对象继承的方法,自己有调自己,自己没有调父类的思想
    }
    package main
    
    import "fmt"
    // 在方法中使用值接受器 与 在函数中使用值接受器
    // 在方法中使用指针接受器 与 在 函数中只要指针接受器
    type Person2 struct {
        name string
        age int
        sex int
    }
    //函数中使用值作为参数
    func printName1(a Person2)  {
        fmt.Println(a.name)
    }
    //函数中使用指针作为参数
    func printName2(a *Person2)  {
        //fmt.Println((*a).name)
        //支持下面的写法
        fmt.Println(a.name)
    }
    //在方法中使用值接受器
    func (a Person2)printName()  {
        fmt.Println(a.name)
    }
    // 在方法中使用指针接受器
    func (a *Person2)printName2()  {
        fmt.Println(a.name)
    }
    
    func main() {
        p:=Person2{name:"kkk"}
        // 调用值接受器
        p.printName()
        // 调用指针接受器
        p.printName2()
    
        //调用值函数
        printName1(p)
        //调用指针函数
        printName2(&p)
    
        //总结:不管是值接受器还是指针接受器,都可以使用值来调用
        //      不管是值接收器还是指针接受器,都可以使用指针来调用
        //      在函数中,是什么参数,就得传什么参数
        pp:=&Person2{name:"kkkk"}
        pp.printName()
        pp.printName2()
    }
    非结构体上绑定方法
    
    package main
    
    import "fmt"
    
    //非结构体上的方法,    (接收器可以是结构体,也可以是非结构体)
    //func (i int)add()  {
    //    i++
    //}
    
    //重命名 ,传统的不支持绑定方法,你可以重命名后绑定方法
    type Myint int
    
    //func (i Myint) add()  {
    //    i++
    //    fmt.Println(i) //11 ,但是fmt.Println(a)为10
    //
    //}
    
    func (i *Myint) add()  {
        (*i)++
            fmt.Println(i)  //打印的是地址
            fmt.Println(*i) // 11
        }
    
    func main() {
        var a Myint=10
        a.add()
        fmt.Println(a) //11
    }

    接口

    package main
    
    import "fmt"
    
    //接口
    /*
    接口是一系列方法的集合
        语法:
            type 接口名 interface {
                方法一
                方法二
                }
    */
    //定义了一个鸭子接口
    type Duck interface{
        run()   //func 关键字省略, 此时该方法没有返回值,可以不写
        speak()   //runn()() 后面第一括号里为参数,第二个括号里为返回值 例如 run(a int)int
    }
    
    //实现该接口(结构体要实现接口,只要该结构体实现了接口中的所有的方法,就实现了该接口)
    //侵入式接口和非侵入式接口
    // java当中必须要实现的接口就是侵入式接口,必须要实现的,只要把那个接口拿掉就会报错,java,c++
    // 在python和go中都是非侵入式接口,可以把接口拿掉,不会影响程序的运行,不会报错,,不会对你代码造成影响
    
    //定义一个普通鸭子的结构体
    type PDuck struct {
        name string
        age string
    }
    
    //实现run方法
    func (p PDuck)run()  {
        fmt.Println("我是普通鸭子,名字叫",p.name,"走路爽歪歪")
    }
    //实现speak
    func (p PDuck)speak()  {
        fmt.Println("我是普通鸭子,名字叫",p.name,"各个说过话")
    }
    
    //定义一个唐老鸭的结构体
    type TDuck struct {
        name string
        age string
        wife bool
    }
    
    //实现run方法
    func (p TDuck)run()  {
        fmt.Println("我是唐老鸭,名字叫",p.name,"走路爽歪歪")
    }
    //实现speak
    func (p TDuck)speak()  {
        fmt.Println("我是唐老鸭,名字叫",p.name,"各个说过话")
    }
    
    func main()  {
        pD:=PDuck{name:"水鸭子"}
        tD:=TDuck{name:"唐老鸭"}
        //写一个函数让鸭子说话,不管是水鸭子,还是唐老鸭
        speak(pD)
        speak(tD)
    
        //定义一个鸭子类型的变量
        var d Duck   //给类型定义变量
        d = pD
        d = tD
        fmt.Println(d)   //类似于面向对象的多态,鸭子有多种形态
    
        // 问题研究,想在函数中拿出唐老鸭的wife属性
        speak(tD)
    }
    
    
    //写一个函数让鸭子说话,不管是水鸭子,还是唐老鸭
    // 只能分别写,下面这种写法太麻烦,代码冗余 改进方法用
    //func speak(p PDuck)  {
    //    p.speak()
    //}
    //func speak2(t TDuck)  {
    //    t.speak()
    //}
    
    //改进方法 传类型
    //func speak(p Duck)  {
    //    //p.speak()   //只要是同一类事物,都可以传过来
    //    // 问题研究,想在函数中拿出唐老鸭的wife属性
    //    //在这里拿属性
    //        //就用类型断言,断言你是TDuck类型,如果没有问题,转成TDuck类型
    //    a:=p.(TDuck)
    //    fmt.Println(a.wife)
    //    p.speak()
    //}
    
    //
    func speak(p Duck)  {
        switch a:=p.(type) { //类型不确定,通过case来进行判断
        case PDuck:
            fmt.Println("你是普通鸭子")
        //    判断是普通鸭子,把普通鸭子的名字拿出来
            fmt.Println(a.name)
        case TDuck:
            //    判断是唐老鸭,把唐老鸭的wife拿出来
            fmt.Println("你是唐老鸭")
            fmt.Println(a.wife)  //在不同的类型中a是不一样的
        }
    }

    空接

    package main
    import "fmt"
    
    //空接口(里面一个方法都没有)
    // 是不是所有的类型都实现了空接口,是
    //所有的类型都可以赋值给空接口
    type Empty interface {
        
    }
    type speaks struct {
        name string
    }
    
    func main()  {
        test(1)
        test("sss")
        p:=speaks{name:"kkk"}
        test(p)
        //什么类型都支持
    
        test4(1)
        test4("sss")
        p1:=speaks{name:"kkkee"}
        test4(p1)
    
    }
    
    func test(a Empty)  {
        fmt.Println(a)
    }
    
    func test4(a interface{})  {
        switch a.(type) {
        case int:
            fmt.Println("我是int类型")
        case string:
            fmt.Println("我是字符串类型")
        default:
            fmt.Println("不知道是什么类型")
        }
    }
    实现多个接口

    接口嵌套

    接口的零值是nil类型,即接口是引用类型
  • 相关阅读:
    Jedis客户端以及redis中的pipeline批量操作
    Redis5.x两种持久化方式以及主从复制配置
    博客园原创文章防剽窃、反爬虫指南(持续更新.....)
    【金主打赏榜】
    Swift LeetCode 目录 | Catalog(每周日更新......)
    [Swift]SkeletonView:在UITableView中使用骨架屏
    【Xcode】加快Xcode编译调试速度
    【Xcode】ITMS-90809:查找UIWebView
    [Swift]PhotoKit-照片框架
    [SourceTree]remote: HTTP Basic: Access denied
  • 原文地址:https://www.cnblogs.com/Fzhiyuan/p/12040351.html
Copyright © 2020-2023  润新知