zoukankan      html  css  js  c++  java
  • Go 结构体 方法 接口

    结构体

    package main
    
    import "fmt"
    
    //结构体:一系列属性的集合
    //定义结构体(在包中定义了)
    
    
    //7 定义一个结构体,内涵匿名字段(字段没有名字)  匿名字段类型就是字段名,所有类型不能重复
    //type Person struct {
    //    string
    //    int
    //    sex string
    //}
    
    
    //8 嵌套结构体(结构体中套结构体)
    
    //type Person struct {
    //    Name string
    //    Age int
    //    sex string
    //    Hobby Hobby
    //}
    //type Hobby struct {
    //    HobbyId int
    //    HobbyName string
    //}
    
    //9 字段提升
    //type Person struct {
    //    Name string
    //    Age int
    //    sex string
    //    Hobby
    //}
    //type Hobby struct {
    //    HobbyId int
    //    HobbyName string
    //}
    
    //type Person struct {
    //    Name string
    //    Age int
    //    sex string
    //    Hobby
    //}
    //type Hobby struct {
    //    Id int
    //    Name string
    //}
    
    
    //11 结构体相等性
    
    type Person struct {
        Name string
        Age int
        sex string
        //包含不可比较的字段
        AAA []int
    }
    
    func main() {
        //1 结构体的使用  值类型
        //var per entity.Person
        //fmt.Println(per)
        //per.Name="lqz"
        //per.Age=19
        //fmt.Println(per)
    
        //2 定义并赋初值
        //var per entity.Person=entity.Person{Name:"lqz"}   //不按位置,少传
        //var per2 entity.Person=entity.Person{"lqz",19,""}   //按位置,全穿
        //fmt.Println(per2)
        //per2.Age=20
        //fmt.Println(per2)
    
        //3 匿名结构体(定义在内部(函数,结构体),只使用一次,没有名字)
        // 有什么用?当定义多个变量(想一次使用),就可以把这多个变量放到匿名结构体中
        //a := struct {
        //    HobbyId   int64
        //    HobbyName string
        //}{HobbyId: 1, HobbyName: "篮球"}
        //
        //fmt.Println(a.HobbyName)
        //a.HobbyName="足球"
        //fmt.Println(a.HobbyName)
    
        //4 结构体的零值,值类型
        //var per entity.Person
        //fmt.Println(per)  //属性的零值,值类型,参数传递,copy传递,在函数中修改,不会影响原来的
        //test2(per)
        //fmt.Println(per)
    
        //5 访问结构体字段 ,通过 . 来访问  注意大小写
    
        //6 结构体的指针
        //var per *entity.Person
        //fmt.Println(per)
    
        //定义并初始化
        //var per *entity.Person=&entity.Person{}
        //fmt.Println(per)
        ////把per的名字改成lqz
        //(*per).Name="lqz"
        ////支持直接使用(数组也是这样,自动帮你处理了)
        //per.Name="egon"
        //fmt.Println(per)
    
    
        //7 匿名字段(字段没有名字,只有类型)
        //【变量提升/提升字段】面向对象的继承
        //per:=Person{"lqz",19,""}
        //per:=Person{string:"lqz",int:19,sex:""}  //字段匿名,类型就是字段名
        //fmt.Println(per)
        //fmt.Println(per.string)
        //fmt.Println(per.int)
    
        //8 嵌套结构体(结构体中套结构体)
        //var per Person =Person{"lqz",19,"",Hobby{1,"篮球"}}
        //var per Person =Person{Name: "lqz",Age: 19,sex: ""}
        //var per Person =Person{Name: "lqz",Age: 19,sex: "",Hobby:Hobby{1,"足球"} }
        //var per Person =Person{Name: "lqz",Age: 19,sex: "",Hobby:Hobby{HobbyId: 1,HobbyName: "足球"}}
        //fmt.Println(per.Name)
        //fmt.Println(per.Hobby.HobbyName)
    
        //9 字段提升
        //var per Person =Person{"lqz",19,"",Hobby{1,"篮球"}}
        //var per Person =Person{Name: "lqz",Age: 19,sex: "",Hobby:Hobby{HobbyId: 1,HobbyName: "足球"}}
        ////打印爱好的名字(Hobby是一个匿名字段,会字段提升)
        //fmt.Println(per.HobbyName)
        //fmt.Println(per.Hobby.HobbyName)  //per.Hobby 类似于面向对象中的super()
        ////像什么?像面向对象的继承  子类继承父类(结构体嵌套,匿名字段),子类可以直接调用父类中的属性或方法
    
        //var per Person =Person{Name: "lqz",Age: 19,sex: "",Hobby:Hobby{ 1, "足球"}}
        //fmt.Println(per.Name)  //优先使用自己的
        ////打印出hobby的名字
        //fmt.Println(per.Hobby.Name)
    
        //10 导出结构体和字段 大写字母开头,在外部包可以使用
    
        //11 结构体相等性
        //结构体是值类型。
        //如果它的每一个字段都是可比较的,则该结构体也是可比较的。 如果两个结构体变量的对应字段相等,则这两个变量也是相等的
        //如果结构体包含不可比较的字段,则结构体变量也不可比较。
    
        //值类型,可以直接==比较,引用类型只能跟nil用==比较
        //per1:=Person{Name: "lqz"}
        //per2:=Person{Name: "lqz",Age:19}
        //fmt.Println(per1==per2)
    
        //per1:=Person{Name: "lqz"}
        //per2:=Person{Name: "lqz",Age:19}
        //fmt.Println(per1==per2) //包含不可比较的属性
        fmt.Println("lqz nb")
    
    }
    //func test2(per entity.Person)  {
    //    per.Age=99
    //    fmt.Println(per)
    //}

    方法

    package main
    
    //方法:特殊函数,在函数的基础上加了一些东西
    //在 func 这个关键字和方法名中间加入了一个特殊的接收器类型,接收器可以是结构体类型,也可以是非结构体类型
    //type Person2 struct {
    //    Name string
    //    Age int
    //    Sex string
    //}
    //
    ////def add(self):
    ////    self.name
    ////    pass
    ////定义一个方法  : (p Person2) 绑定给了Person2结构体的对象
    //func (p Person2) printName()  {
    //    //在方法内可以使用p
    //    fmt.Println(p.Name)
    //}
    ////修改名字
    //func (p Person2) changeName(name string)  {
    //    p.Name=name
    //    fmt.Println(p)
    //}
    ////修改年龄方法
    //func (p *Person2) changeAge(age int)  {
    //    //fmt.Println(p.Age)  //推荐用这个
    //    p.Age=age
    //}
    //
    //func printName(p Person2)  {
    //    fmt.Println(p.Name)
    //}
    
    
    // 匿名字段的方法
    //type Person2 struct {
    //    Name string
    //    Age int
    //    Sex string
    //    Hobby  //匿名字段
    //}
    //type Hobby struct {
    //    Id int
    //    Name string
    //}
    //
    ////给结构体绑定方法
    //func (p Person2)printName()  {
    //    fmt.Println(p.Name)
    //}
    ////func (h Hobby)printHobbyName()  {
    //func (h Hobby)printName()  {
    //    fmt.Println(h.Name)
    //}
    
    
    
    /// //6 在方法中使用值接收器 与 在函数中使用值参数
    //type Person2 struct {
    //    Name string
    //    Age int
    //    Sex string
    //}
    ////在方法中使用值接收器
    //func (p Person2)printName()  {
    //    fmt.Println(p.Name)
    //}
    //func (p Person2)changeName(name string)  {
    //    p.Name=name
    //    fmt.Println(p)
    //}
    ////在函数中使用值参数
    //func printName(p Person2)  {
    //    fmt.Println(p.Name)
    //}
    
    
    //7 在方法中使用指针接收器 与 在函数中使用指针参数
    //type Person2 struct {
    //    Name string
    //    Age int
    //    Sex string
    //}
    ////在方法中使用值接收器
    //func (p *Person2)printName()  {
    //    fmt.Println(p.Name)
    //}
    //func (p *Person2)changeName(name string)  {
    //    p.Name=name
    //    fmt.Println(p)
    //}
    ////在函数中使用指针参数
    //func printName(p *Person2)  {
    //    //fmt.Println((*p).Name)
    //    fmt.Println(p.Name)
    //}
    
    
    
    //8 非结构体上的方法(不允许)自己定义的类型可以绑定方法
    //在int类型上绑定一个add方法
    //不允许
    //func (i int)add(){
    //    i=i+1
    //    i++
    //    //i+=1
    //}
    
    // 可以在自定义的类型上绑定方法
    type Myint  int
    func (i *Myint)add(){
        (*i)=(*i)+1
        //i++
        //i+=1
    }
    func main() {
    
        //1 方法的定义和使用
        //per:=Person2{}
        //per.Name="lqz"
        //per.printName()  //绑定给对象的方法
        //
        //per1:=Person2{Name: "egon"}
        //per1.printName()
    
        //2 为什么我们已经有函数了还需要方法呢?
        //per1:=Person2{Name: "egon"}
        ////per1.printName()  //方法的特殊之处,可以自动传值
        ////
        ////printName(per1)
        //per1.changeName("lqz")
        //
        ////并没有改
        //fmt.Println(per1)
    
        //3 指针接收器与值接收器
        //per1:=Person2{Name: "egon",Age: 18}
        //fmt.Println(per1)
        //per1.changeAge(99)
        //fmt.Println(per1)
    
        //4 时候使用指针接收器,什么时候使用值接收器:想改原来的,就用指针,不想改原来的就用值(指针用的多)
    
        //5 匿名字段的方法(方法提升)
    
        //per1:=Person2{Name: "lqz",Hobby:Hobby{1,"足球"}}
        ////per1.printHobbyName()  //Hobby是个匿名字段,方法也提升了
        ////如果方法名冲了,优先用该结构体自己的
        //per1.printName()
        //per1.Hobby.printName()
    
        //6 在方法中使用值接收器 与 在函数中使用值参数
        //per1:=Person2{Name: "lqz"}
        //per1.printName()
        //printName(per1)
    
        //per1:=&Person2{Name: "lqz"}  //per1是个指针
        //per1.printName()
        //printName(*per1)
    
        //小研究
        //per1:=&Person2{Name: "lqz"}  //per1是个指针
        //per1.changeName("egon")
        //fmt.Println(per1)
    
        //值收器:可以用值来调,也可以用指针来调
        //函数的值参数,只能传值
    
        //7 在方法中使用指针收器 与 在函数中使用指针参数
    
        //per1:=Person2{Name: "lqz"}
        //per1.printName()  //值可以来调用
        //printName(&per1)
    
        //per1:=&Person2{Name: "lqz"}
        //per1.printName()  //指针可以来调用
        //printName(per1)
    
        //小研究
        //per1:=Person2{Name: "lqz"}
        //per1.changeName("egon")
        //fmt.Println(per1)
    
        //per1:=&Person2{Name: "lqz"}
        //per1.changeName("egon")
        //fmt.Println(per1)
    
        //总结:不管是值类型接收器还是指针类型接收器,都可以用值来调用,或者指针来调用
        //总结:不管是值还是指针来调用,只要是值类型接收器,改的就是新的,只要是指针类型接收器,改的是原来的
        //a:=1
        //a+=1
        //a++
        //a=a+1
        //++a  //java中有++a
        //fmt.Println(a)
    
        //8 非结构体上绑定方法
        //var a Myint =10
        //fmt.Println(a)
        //a.add()
        //a.add()
        //a.add()
        //a.add()
        //fmt.Println(a)
        //
    
    
    
        //var b =11
        ////fmt.Println(a+b)  //类型不匹配
        //
        //c:=a+Myint(b)
        //fmt.Println(a+Myint(b))  //类型匹配
        //d:=int(a)+b
        //fmt.Println(int(a)+b)  //类型匹配
    
    
    }

    接口

    package main
    
    //go也是鸭子类型:我现在有个鸭子类,内有speak方法   有run方法,  子类只要实现了speak和run,我就认为子类是鸭子
    //在java中,子类必须实现鸭子类的所有方法,子类才叫鸭子
    //接口:面向对象的领域里,接口一般这样定义:接口定义一个对象的行为,规范子类对象的行为
    //接口:是一系列方法的集合(规范行为)
    
    //1 定义接口(定义一个鸭子接口,speak方法,run方法)
    //type Duck interface {
    //    speak()  //speak()方法
    //    run()
    //}
    //
    ////定义一个普通鸭子结构体
    //type PDuck struct {
    //    name string
    //    sex string
    //    age int
    //}
    //
    ////定义一个唐老鸭结构体
    //type TDuck struct {
    //    name string
    //    sex string
    //    age int
    //    wife string
    //}
    ////让唐老鸭和普通鸭子都实现Duck接口
    ////结构体实现一个接口:只要绑定接口中的所有方法,就叫实现该接口
    //func (p PDuck)speak()  {
    //    fmt.Println("普通鸭子嘎嘎叫,普通鸭子名字叫",p.name)
    //}
    //func (p PDuck)run()  {
    //    fmt.Println("普通鸭子歪歪扭扭走了,普通鸭子名字叫",p.name)
    //}
    //
    ////唐老鸭也实现Duck接口
    //func (p TDuck)speak()  {
    //    fmt.Println("唐老鸭说人话,唐老鸭子名字叫",p.name)
    //}
    //func (p TDuck)run()  {
    //    fmt.Println("唐老鸭人走路,唐老鸭子名字叫",p.name)
    //}
    //
    //
    ////6 空接口定义
    //type Empty interface {
    //}
    
    func main() {
        //1 得到一个普通鸭子对象
        //pduck:=PDuck{"黑子","",1}
        //pduck.run()
        //pduck.speak()
        ////2 得到一个堂老鸭子对象
        //tduck:=TDuck{"egon","",1,"刘亦菲"}
        //tduck.run()
        //tduck.speak()
    
        //侵入式接口(接口没了,子类报错)和非侵入是接口(接口没了,不影响代码,go语言中的接口是非侵入式的)
    
        //2 接口的实际用途(接口也是一个类型)
        //var duck Duck
        ////pduck:=PDuck{"黑子","",1}
        //tduck:=TDuck{"egon","",1,"刘亦菲"}
        ////duck=pduck
        //duck=tduck  //多态,同一类事务多种形态
        //duck.run()
    
        //3 接口内部表示
        //我们可以把接口看作内部的一个元组 (type, value)。
        //type 是接口底层的具体类型(Concrete Type),而 value 是具体类型的值。
    
        //4 把接口类型转成struct,属性,自有方法也有了,类型断言
        //类型断言
        //var duck Duck =TDuck{"egon","",1,"刘亦菲"}
        ////断言是TDuck类型
        ////v, ok := duck.(TDuck)
        //////断言成功,ok是true,v就是TDuck结构体对象
        ////fmt.Println(v)
        ////fmt.Println(v.name)
        ////fmt.Println(ok)
        //
        ////断言失败
        //var v PDuck
        //var ok bool
        //v, ok = duck.(PDuck)
        ////断言失败,ok是false,v是PDuck类型的空置,因为没有复制
        //fmt.Println(ok)
        //fmt.Println(v)
    
        //5 类型选择(通过switch)
        //var duck Duck =TDuck{"egon","",1,"刘亦菲"}
        ////var duck Duck =PDuck{"egon","",1}
        //test4(duck)
    
        //6 空接口(没有任何方法,所有数据类型都实现了空接口)
        //var a int=10
        //var b string="lqz"
        //var c [3]int
        //var e Empty  //空接口类型
        //e=a
        //e=b
        //e=c
        //fmt.Println(e)
        //fmt.Println(1,"xxx")
        //test5(a)
        //test5(b)
        //test5(c)
    
        //7 匿名空接口 没有名字的空接口  一般用在形参上
        //test6(10)
        //test6("lll")
        //var duck TDuck =TDuck{"egon","",1,"刘亦菲"}
        //test6(duck)
    
        //8 之前学过的集合类型,都可以放接口类型
        //var a[3]Duck
        //a[1]=PDuck{}
        //a[2]=TDuck{}
        //var a map[string]interface{}= make(map[string]interface{})
        //a["name"]="lqz"
        //a["age"]=19
        //a["duck"]=PDuck{}
    
    
    }
    //func test6(b interface{})  {
    //    fmt.Println(b)
    //}
    
    
    
    //func test5(b Empty)  {
    //    switch v:=b.(type) {
    //    case string:
    //        fmt.Println("我是字符串")
    //        fmt.Println(v)
    //    case int:
    //        fmt.Println("我是int")
    //        fmt.Println(v)
    //    case [3]int:
    //        fmt.Println("我是数组")
    //        fmt.Println(v)
    //    }
    //}
    
    
    
    //func test4(duck Duck)  {
    //    if v,ok:=duck.(TDuck);ok{
    //        fmt.Println("我是普通鸭子")
    //        fmt.Println(v)
    //    }else if v,ok:=duck.(PDuck);ok {
    //        fmt.Println("我是普通鸭子")
    //        fmt.Println(v)
    //    }
    //}
    
    //使用switch,选择成功,拿到结构体对象
    //func test4(duck Duck)  {
    //    switch v:=duck.(type) {
    //    case PDuck:
    //        fmt.Println(v.name)
    //        fmt.Println("我是普通鸭子")
    //    case TDuck:
    //        fmt.Println(v.wife)
    //        fmt.Println("我是唐老鸭")
    //    default:
    //        fmt.Println(v)
    //        fmt.Println("我是鸭子这个类")
    //
    //    }
    //}

     make和new的区别

    package main
    
    //make和new的区别
    type PDuck1 struct {
        name string
        sex string
        age int
    }
    func main() {
        //make是引用类型初始化的时候用的
        //var per *PDuck1 =new(PDuck1)    //new 是返回指向这个类型的指针
        //fmt.Println(per)
        //
        //
        //var per1 =&PDuck1{}
        //fmt.Println(per1)
    
        //var per2 = make([]int,3,4)  //make是具体的造引用类型  //new是造指向这个类型的指针
        //var per2 *[]int= new([]int)
        //fmt.Println(per2)
        //(*per2)=append((*per2),99)
        //fmt.Println(per2)
    
    
    }

    结构体取代类

    package main
    
    import (
        person "day04/Person"
        "fmt"
    )
    
    func main() {
        per :=person.New("lqz",19,"")
    
        //var per Person = new Person("lqz",19,"")
        fmt.Println(per)
        per.PrintName()
    }
  • 相关阅读:
    OpenGL(十一) BMP真彩文件的显示和复制操作
    OpenGL(十) 截屏并保存BMP文件
    复数的认识与理解
    复数的认识与理解
    采样定理
    采样定理
    How Many Fibs_hdu_1316(大数).java
    FZOJ2110 star(DFS)
    透过表象看本质!?之二数据拟合
    设计中的道理_3
  • 原文地址:https://www.cnblogs.com/ZhZhang12138/p/14886734.html
Copyright © 2011-2022 走看看