• Go04基础


    1 结构体

    1 结构体的使用  值类型
    	定义:
            type Person struct {
            	Name string
            	Age int
            	sex string       	
            }
        使用:   
    	var per Person
    	fmt.Println(per)
    	per.Name="lqz"
    	per.Age=19
    	fmt.Println(per)
    2 定义并赋初值
    	var per =Person{Name:"lqz"}   //不按位置,少传
    	var per2 n=entity.Person{"lqz",19,"男"}   //按位置,全穿
    	fmt.Println(per2)
    	per2.Age=20
    	fmt.Println(per2)
    3 匿名结构体(定义在内部(函数,结构体),只使用一次,没有名字)
    	 有什么用?当定义多个变量(想一次使用),就可以把这多个变量放到匿名结构体中
    	a := struct {
    		HobbyId   int64
    		HobbyName string
    	}{HobbyId: 1, 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 *Person
    	fmt.Println(per)
    	定义并初始化
    	var per *Person=&Person{}
    	fmt.Println(per)
    	//把per的名字改成lqz
    	(*per).Name="lqz"
    	//支持直接使用(数组也是这样,自动帮你处理了)
    	per.Name="egon"
    	fmt.Println(per)
    7 匿名字段(字段没有名字,只有类型)
    	【变量提升/提升字段】面向对象的继承
        type Person struct {	
            string
            int
            sex string
            Hobby
        }
    	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 字段提升
        type Person struct {	
            Name string
            Age int
            sex string
            Hobby
        }
        type Hobby struct {
            Id int
            Name string
        }
    	var per Person =Person{"lqz",19,"男",Hobby{1,"篮球"}}
    	//打印爱好的名字(Hobby是一个匿名字段,会字段提升)
    	fmt.Println(per.HobbyName)
    	fmt.Println(per.Hobby.HobbyName)  //per.Hobby 类似于面向对象中的super()
    	//像什么?像面向对象的继承  子类继承父类(结构体嵌套,匿名字段),子类可以直接调用父类中的属性或方法
    10 导出结构体和字段 大写字母开头,在外部包可以使用
    11 结构体相等性
    	结构体是值类型。
    	如果它的每一个字段都是可比较的,则该结构体也是可比较的。 如果两个结构体变量的对应字段相等,则这两个变量也是相等的
    如果结构体包含不可比较的字段,则结构体变量也不可比较。
    

    2 方法

    package main
    
    //方法:特殊函数,在函数的基础上加了一些东西
    //在 func 这个关键字和方法名中间加入了一个特殊的接收器类型,接收器可以是结构体类型,也可以是非结构体类型
    type Person2 struct {
    	Name string
    	Age int
    	Sex string
    }
    
    func (p Person2) printName()  {
    在方法内可以使用p
    	fmt.Println(p.Name)
    }
    修改名字、
    1.值传递
    func (p Person2) changeName(name string)  {
    	p.Name=name
    	fmt.Println(p)  //值传递  无法修改原来的
    }
    修改年龄方法
    2.引用传递
    func (p *Person2) changeAge(age int)  {
    	fmt.Println(p.Age)  //推荐用这个
    	p.Age=age
    }    //引用   可以修改原来的
    
    
    
    3.匿名字段的方法
    	方法提升
    
    4.在方法中使用值接收器 与 在函数中使用值参数
    type Person2 struct {
    	Name string
    	Age int
    	Sex string
    }
    5.在方法中使用值接收器
    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)
    }
    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)
    	fmt.Println(p.Name)
    }
    //值收器:可以用值来调,也可以用指针来调
    //函数的值参数,只能传值
    //总结:不管是值类型接收器还是指针类型接收器,都可以用值来调用,或者指针来调用
    //总结:不管是值还是指针来调用,只要是值类型接收器,改的就是新的,只要是指针类型接收器,改的是原来的
    7.非结构体上的方法(不允许)自己定义的类型可以绑定方法
    	可以在自定义的类型上绑定方法
    type Myint  int
    func (i *Myint)add(){
    	(*i)=(*i)+1
    	i++
    	i+=1
    }
    

    3 接口

    //go也是鸭子类型:我现在有个鸭子类,内有speak方法   有run方法,  子类只要实现了speak和run,我就认为子类是鸭子
    //在java中,子类必须实现鸭子类的所有方法,子类才叫鸭子
    //接口:面向对象的领域里,接口一般这样定义:接口定义一个对象的行为,规范子类对象的行为
    //接口:是一系列方法的集合(规范行为)
    1 定义接口(定义一个鸭子接口,speak方法,run方法)
    type Duck interface {
    	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)
    }
    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结构体对象
    	v, ok = duck.(PDuck)    //断言失败,ok是false,v是PDuck类型的空置,因为没有复制
    5 类型选择(通过switch)
    func test(a 接口名字){
        switch v:=a.(type){
            case type1:
                此时v就是type1的结构体
            case type2:
                此时v就是type2的结构体
            ...      
        }
    }
    6 空接口(没有任何方法,所有数据类型都实现了空接口)
    7 匿名空接口 没有名字的空接口  一般用在形参上
    8 之前学过的集合类型,都可以放接口类型
    	var a map[string]interface{}= make(map[string]interface{})
        a["name"]="lqz"
    	a["age"]=19
    	a["duck"]=PDuck{}
    9 接口的零值
    	nil 
    10  接口的嵌套
    type Animal interface {
    	eat()
    	sleep()
    }
    type Duck interface {
    	Animal    //套用之前的
    	speak()
    	run()
    }
    11.重要概念*****
    	*****接口是一种类型,一个结构体可以实现多种接口,当该结构体可以被转成某种接口,只能使用该接口的方法,当然,该接口也可以转成另一种接口,也可以转成结构体
    

    4 make和new的区别

    make是引用类型初始化的时候用的	
    new 是返回指向这个类型的指针
    //var per *PDuck1 =new(PDuck1)    //new 是返回指向这个类型的指针
    //var per2 = make([]int,3,4)  //make是具体的造引用类型  
    

    5 结构体取代类(给结构体设置默认值)

    1.test包下下
    	package test
    	定义一个结构体
        type Cat struct {
            Name string
            Age  int
        }
    	func new()  Cat {
            return Cat{Name:"默认值"...}    
    }
    2.在其他包调用
    	cat:=test.new()  //也可以设置成传参数
    
    永远不要高估自己
  • 相关阅读:
    json2源码
    在table中插入别的代码
    基于HTML5和Javascript的移动应用架构
    webkitscrollbar
    性能调优之Javascript内存泄漏
    javascript时区函数介绍
    几道面试题
    CSS property: webkitbackfacevisibility
    某人2013js趋势的一些判断
    用js操作cookie保存浏览记录
  • 原文地址:https://www.cnblogs.com/liqiangwei/p/14508312.html
Copyright © 2020-2023  润新知