GO语言四

1 指针

package main

//指针:指针是一种存储    变量内存地址的    变量
//1 取一个变量的地址:&  取地址符号
//2 如果在类型前面加*,表示指向这个类型的指针
//3 在指针变量前加*,表示解引用(反解),通过地址拿到值


func main() {
	//1 指针的定义
	//var b int=156
	////把b的内存地址赋值给a这个指针
	//var a *int=&b
	////var c *string =&b   //int类型指针是不能赋值给字符串类型的指针
	////a:=&b
	//fmt.Println(a)

	//2 指针的零值(nil)
	//var b *int
	//fmt.Println(b)

	//3 指针的解引用(拿到地址指向的值)
	//var b=156
	//a:=&b
	//
	//fmt.Println(a)
	////指针a指向的值:解引用(反解)
	//fmt.Println(*a)

	//4 向函数传递指针参数
	//var b =156
	//fmt.Println(b)
	//test(&b)
	//fmt.Println(b)
	//5 不要向函数传递数组的指针,而应该使用切片
	//var a [4]int=[4]int{3,4,5}
	//	////写一个函数,传入数组,该掉原来的数组
	//	//fmt.Println(a)
	//	//test(&a)
	//	////fmt.Println(a)
	//	////向函数传递切片
	//	//test1(a[:])
	//	//fmt.Println(a)

	//6 Go 不支持指针运算
	//var b [3]int=[3]int{1,2,3}
	//a:=&b
	//不允许指针运算
	//fmt.Println(*(a++))

	//7 指向指针的指针
	//var b int=156
	//var a *int=&b
	//var c **int
	//c=&a
	//var d ***int
	//d=&c
	//fmt.Println(d)
	//fmt.Println(*d)
	//fmt.Println(**d)
	//fmt.Println(***d)
	//6 数组指针和指针数组
	  // 数组指针:指向数组导入指针
	  //var a [3]int=[3]int{1,2,3}
	  //var b *[3]int=&a
	  //fmt.Println(b)
	 // 指针数组:数组里面放指针
	 //var x,y,z=12,13,14
	 //var b [3]*int =  [3]*int{&x,&y,&z}
	 //fmt.Println(b)



}

//func test1(x []int)  {
//	x[0]=100
//	fmt.Println(x)
//}
//func test(x *[4]int)  {
//	//x[0]=100  //支持指针直接操作(内部处理的),自动反解,自动解引用
//	(*x)[1]=100  //正统写法
//	fmt.Println(x)  //x是个指向数组的指针,地址  打印出:&[3 100 5]
//	fmt.Println(*x)
//}


//func test(b *int)  {
//	//解引用,然后操作  b是一个指针
//	*b+=10
//	fmt.Println(*b)
//}


2 结构体

package main

//结构体取代类(go语言中的结构体,类似于面向对象语言中的类)
// go中的面向对象:继承,封装,多态

//结构体:是一系列属性的集合    python中的类:一系列属性和方法的集合

//1 定义一个结构体
/*
type 结构体名字 struct {
	属性 类型
	属性 类型
}
 */
//大小写表示公有和私有
type Person struct {
	name string
	age int
	sex int
}


// 匿名字段(字段没有名字)
type Person2 struct {
	 string  //姓名
	 int    //年龄
}

//结构体嵌套
//type Hobby struct {
//	id int
//	name string
//}
//type Person3 struct {
//	name string
//	age int
//	sex int
//	hobby Hobby
//}
//字段提升
type Hobby struct {
	id int
	hobbyName string
}
type Person3 struct {
	name string
	age int
	sex int
	Hobby
}

func main() {
	//2 结构体使用
	//var p Person=Person{}  //相当于实例化得到一个对象
	////p:=Person{}  //相当于实例化得到一个对象
	//fmt.Println(p)
	//fmt.Println(p.name)

	//3 结构体的零值  //值类型,零值是属性的零值
	//var p Person
	//p.name="lqz"
	//fmt.Println(p)

	//4 定义并初始化(传入属性)
	//4.1 按位置传(顺序不能变,有几个值就要传几个值)
	//var p Person=Person{"lqz",18,1}
	//4.2 按关键字传(位置可以乱,可以少传)
	//var p Person=Person{sex:1,age:18}
	//fmt.Println(p)
	//fmt.Println(p.name)

	//5 创建匿名结构体(没有名字也没有type关键字,定义再函数内部)
	//只使用一次,把一堆属性放到一个变量中
	//	a:=struct {
	//		name string
	//		age int
	//		sex int
	//	}{age:18}
	//	//var name="lqz"
	//	//var age=19
	//	//var sex=1
	//	//name="lqz"
	//	fmt.Println(a.age)

	//6结构体的指针
	//var p Person=Person{sex:1,age:18}
	//var p1 *Person=&Person{sex:1,age:18}
	//var p1 *Person
	//fmt.Println(p1)

	//7 匿名字段(字段没有名字)(做变量提升,提升字段:面向对象中的继承)
	//7.1 按位置
	//var p Person2=Person2{"lqz",18}
	//7.2 按关键字(类型就是关键字)
	//var p Person2=Person2{int:18,string:"lqz"}
	//fmt.Println(p)

	//8 嵌套结构体(结构体中套结构体)
	//8.1按位置
	//var p Person3=Person3{"lqz",18,1,Hobby{1,"篮球"}}
	//8.2 按关键字
	//var p Person3=Person3{name:"lqz",hobby:Hobby{}}
	////把hobby id设置成2,name设置成篮球
	//p.hobby.name="篮球"
	//p.hobby.id=2
	//fmt.Println(p)

	//9 提升字段(只把不重复的字段提升)
	//9.1按位置
	//var p Person3=Person3{"lqz",18,1,Hobby{1,"篮球"}}
	//9.2 按关键字(面向对象的继承)
	//var p Person3=Person3{name:"lqz",Hobby:Hobby{}}
	//p.hobbyName="篮球"
	//p.id=2
	//p.Hobby.id=3
	//fmt.Println(p)

	//go中通过匿名字段和结构体嵌套实现面向对象的继承
	//10 导出结构体(大小写)和字段(大小写)

	//11 结构体想等性:
	//结构体是值类型。
	//如果它的每一个字段都是可比较的,则该结构体也是可比较的。 如果两个结构体变量的对应字段相等,则这两个变量也是相等的
	//如果结构体包含不可比较的字段,则结构体变量也不可比较。

}

3 方法

package main

import "fmt"

//方法:      python:什么是方法(绑定给对象,类,自动传值),什么是函数?
//方法是绑定给结构体的:结构体只有属性+方法---》类
//func 这个关键字和   方法名中间    加入了一个特殊的接收器类型
//func (t Type) methodName(parameter list) {
//}

//1 定义方法
//定义一个结构体
type Person4 struct {
	name string
	age int
	sex int
}
//给结构体绑定方法(printName)
func (p Person4)printName()  {
	fmt.Println(p.name)
}
//普通函数
func printName(p Person4)  {
	fmt.Println(p.name)
}

//3 指针接收器与值接收器
func (p Person4)changeName(name string)  {
	p.name=name
	fmt.Println(p)
}
//指针类型接收器的修改年龄
func (p *Person4)changeAge(age int)  {
	//(*p).age=age  //正统的想法
	p.age=age       //go支持的
	fmt.Println(p)
}
func main() {
	//2 使用方法
	//p:=Person4{"lqz",18,1}
	////自动传值
	//p.printName()
	////为什么我们已经有函数了还需要方法呢?
	//printName(p)

	//3 值接收器和指针接收器
	//值接收器,不会修改原来的,指针接收器才会修改原来的
	//p:=Person4{"lqz",18,1}
	//(&p).changeName("egon")
	//(&p).changeAge(100)
	//fmt.Println(p)
	// 不管是值类型接收器还是指针类型接收器,都可以用值和指针来调用
	//4 那么什么时候使用指针接收器,什么时候使用值接收器
	//指针接收器也可以被使用在如下场景:当拷贝一个结构体的代价过于昂贵时

	//5 匿名字段的方法


}




package main

import "fmt"

//匿名字段的方法

type Hobby1 struct {
	id int
	hobbyName string
}
type Person5 struct {
	name string
	age int
	sex int
	Hobby1   //匿名字段
}

//Hobby1的绑定方法
func (h Hobby1)printName()  {
	fmt.Println(h.hobbyName)

}
//Person5的绑定方法
func (p Person5)printName()  {
	fmt.Println(p.name)
}

func main() {
	//5 匿名字段的方法,匿名字段的方法也提升
	//p:=Person5{}
	////方法也提升
	//p.hobbyName="篮球"
	////p.printName()  //继承,子类没有printName,就会调用父类的printName方法
	//p.printName()
	////就要调用父类的printName(面向对象中的super)
	//p.Hobby1.printName()

	//6 在方法中使用值接收器 与 在函数中使用值参数
	//指针和值都可以来调用,    只能传值
	//7 在方法中使用指针接收器 与 在函数中使用指针参数
	// 指针和值都可以来调用       只能传递指针

	//8 在非结构体上的方法(向给int类型绑定个add方法可以吗?)
	//var i int =10
	//i.add()

	var i Myint=10
	i.add()
	i.add()
	i.add()
	i.add()
	fmt.Println(i)


}
//给传统数据类型重命名,然后绑定方法
type Myint int  //把int类型重命名为Myint

func (i *Myint)add()  {
	(*i)=(*i)+1
}

4 接口

package main

import "fmt"

// 接口:接口定义一个对象的行为,一系列方法的集合

//abc规范了子类应该有哪些行为,用abc模块来规范子类的行为
//django中:父类  写了一个方法,没有代码,只有个raise  ,子类继承,但是没有重写该方法,一调用就报错

//1 定义一个鸭子接口(run方法   speak方法)
type DuckInterface interface {
	run()
	speak()
}

//写一个唐老鸭结构体,实现该接口
type TDuck struct {
	name string
	age int
	wife string
}
//实现接口(只要结构体绑定了接口中的所有方法,就叫做:结构体实现了该接口)

func (t TDuck)run()  {
	fmt.Println("我是唐老鸭,我的名字叫",t.name,"我会人走路")
}
func (t TDuck)speak()  {
	fmt.Println("我是唐老鸭,我的名字叫",t.name,"我说人话")
}

//写一个肉鸭结构体,实现该接口
type RDuck struct {
	name string
	age int

}
//实现接口(只要结构体绑定了接口中的所有方法,就叫做:结构体实现了该接口)

func (t RDuck)run()  {
	fmt.Println("我是肉鸭,我的名字叫",t.name,"我会人走路")
}
func (t RDuck)speak()  {
	fmt.Println("我是肉鸭,我的名字叫",t.name,"我说人话")
}

func main() {
	//var t TDuck=TDuck{"嘤嘤怪",18,"刘亦菲"}
	//var r RDuck=RDuck{"建哥",18}
	////唐老鸭的run方法
	//t.run()
	////肉鸭的run方法
	//r.run()

	//定义一个鸭子接口类型(因为肉鸭和唐老鸭都实现了鸭子接口,所有可以把这俩对象赋值给鸭子接口)
	var i1 DuckInterface
	i1=TDuck{"嘤嘤怪",18,"刘亦菲"}
	var i2 DuckInterface
	i2=RDuck{"建哥",18}
	//唐老鸭的run方法
	i1.run()
	//肉鸭的run方法
	i2.run()
	
	
}

//func run(i DuckInterface)  {
//	i.run()
//}

////a 可以是字典,字符串,列表
//len(a)   a.__len__()
////len(str)



posted @ 2020-03-30 19:24  MiaoQinHong  阅读(217)  评论(0编辑  收藏  举报