go语言学习笔记3

go结构体

go支持面向对象编程(OOP),struct是值传递

//struct变量都有默认值

type Cat struct {
	Name string
	Age int
	Color string
}

var cat Cat
cat.Name = "micky"
cat.Age = 3
cat.Color = "Red"
fmt.Println(cat)
fmt.Println(cat.Name)
fmt.Println(&cat) //cat的地址

在这里插入图片描述

  • 结构体的名字如果是大写代表可以被其他包使用
  • 如果属性是指针,map,切片需要先make才能使用
type Person struct {
	Name string
	arr [3]int
	prt *int
	slice []int
	maps map[string]string
}

//第一种定义对象
var man Person
man.ptr = new(int)

man.slice = make([]int, 10)
man.slice[0] = 1

man.maps = make(map[string]string)
man.maps["key"] = "value" 

// 第二种定义对象
man := Person{"elle", 18}

//第三种定义对象
var man *Person = new(Person) 
(*man).Name = "Bella"
(*man).Age = 23
man.Age = 33 //同上种写法
fmt.Println(*man)

//第四种定义对象
var man *Person = &Person{"elle", 18}
(*man).Age = 23
man.Age = 33 //同上种写法,为方便开发者,底层仍是延续上种方式

  • 结构体之间强转需要元素的类型和名字完全一致
type Cat struct {
	Num int
}

type Dog struct {
	Num int
}

func main() {
	var cat Cat 
	var dog Dog 
	dog = Cat (cat)    //强制转换
}

在这里插入图片描述

  • 结构体tag
import "encoding/json"

//json序列号成json
cat := Cat{"mimi", 3, "yellow"}
json_cat,_ := json.Marshal(cat)
fmt.Println(json_cat) //返回的是byte[]切片类型
fmt.Println(string(json_cat)) //返回的是Name大写首字母的json格式

//解决方案:打tag
type Cat struct {
	Name string `json: "name"`
	Age int `json: "age"`
	Color string `json: "color"`
}
go方法

方法是作用在指定类型的,自定义类型都可以有方法
定义:func (cat Cat) test(参数列表) 返回值类型 {}
在这里插入图片描述
主函数里的p对象传给方法时同函数都是值传递,不会改变主函数的值

  • 自定义类型
type interger int

func (i interger) print() {
	fmt.Println(i)
}

func main(){
	var i interger = 10
	i.print()
}
  • 方法和函数的区别
    函数:传递的参数必须和定义时保持一致
    在这里插入图片描述
    方法:传递的参数必须和定义时可以不一致
    在这里插入图片描述
    值拷贝
go工厂模式

go里没有构造函数,用工厂模式替代

使用场景:结构体首字母小写,本不能被其他包使用,但仍有被其他包使用的需求

解决办法:在结构体外包一层函数,指向这个结构体
在这里插入图片描述
在其他包的main函数调用
在这里插入图片描述
如果结构体里的元素score是小写的,即使外面包了一层NewStudent仍不能被其他包调用,若想使用小写的结构体内元素还需要单独给元素包一层
在这里插入图片描述
在其他文件调用时
在这里插入图片描述

go三大特征

封装:就是把抽象出的字段和对字段的操作封装在一起
封装好处:隐藏实现细节

继承:通过匿名结构体实现

type Student struct {
	Name string,
	Age int,
	Score int,
}

type Pupil struct {
	Student //继承Student 
}
type Graduate struct {
	Student //继承Student 
}

// 使用指针可以直接修改main里定义的对象
func (stu *Student) ShowInfo() {
	fmt.Printf("name=%v,age=%v,score=%v", stu.Name, stu.Age, stu.Score)
}
func (stu *Student) setScore(score int) {
	stu.Score = score
}

func (p *Pupil) testing() {
	fmt.Println("pupil is testing...")
}
func (p *Graduate ) testing() {
	fmt.Println("Graduate is testing...")
}

func main() {
	pupil := Pupil{"mike", 7, 0}
	pupil.Student.Name = "jack" 
	pupil.Name = "amber"   
	//这2种赋值不等价,因为如果Pupil类里还有个Name元素是允许的
	
	pupil.testing()
	pupil.setScore(90)
}
  • 同时继承多个结构体
type Goods struct {
	Name string
	Price string
}
type Brand struct {
	Name string
	Address string
}

type TV struct {
	Goods 
	Brand
}

type TV2 struct {
	*Goods 
	*Brand
}
func main() {
	// 注意末尾的,不要忘记
	tv1 := TV{Goods{"tv", 1000}, Brand{"haier", "china"},}
	tv2 := TV{&Goods{"tv", 1000}, &Brand{"haier", "china"},}
	// 先取Goods的地址,再拿到值
	fmt.Println(*tv2.Goods)
}
go接口

type 接口名 interface {
方法1 //不需要实现
方法2
}

func (t 自定义类型)方法1(参数列表) 返回值列表{
实现
}

type Usb interface {
	Start()
	Stop()
}

type Phone struct {
}

type Camera struct {
}

type Computer struct {
}

// phone
func (p Phone) Start(){
	fmt.Println("Phone starting...")
}
func (p Phone) Stop(){
	fmt.Println("Phone stoping...")
}

// camera
func (c Camera ) Start(){
	fmt.Println("Camera starting...")
}
func (c Camera ) Stop(){
	fmt.Println("Camera stoping...")
}

//computer
func (com Computer) work(usb Usb){
	usb.Start()
	usb.Stop()
}

// assert
func (p Phone) Call() {
	fmt.Println("Phone calling...")
}

func main(){
	computer := Computer{}
	phone := Phone{}
	camera := Camera{}
	
	//谁实现了interface就可以作为参数传递
	computer.work(phone)
	computer.work(camera)
	
	//多态数组,通过接口实现一个数组内存放多种类型数据
	var arr [3]usb
	usb[0] = Phone{}
	usb[1] = Camera{}
}
  • 接口注意事项
  1. 接口不可以实例化,但可以定义一个实现了该方法的结构体指向它
    在这里插入图片描述
  2. 接口中的每一个方法都要实现
  3. 自定义类型(type interger int)也可以实现接口方法
  4. 接口中不允许有任何变量
  5. 接口直间可以相互继承,若想实现子接口必须实现父接口
  6. interface是引用类型
  7. interface{}是一种数据类型,所有类型都实现了空接口

多态:通过接口实现,接口是对继承的补充

go断言
type Point struct{
	x int
	y int
}
func main(){
	var a interface{}
	a = Point(1,2)
	var b Point
	b = a  //不可以
	b = a.(Point) //断言
	
	// 断言判断
	b, flag = a.(Point) 
	if flag {
		fmt.Println("convert success")
	}else{
		fmt.Println("convert fail")
	}
	
}

🤭:判断a是否是指向Point类型的变量,如果是则将a转换为Point赋值给b,不是则报错

func (com Computer) work(usb Usb){
	usb.Start()
	phone,ok := usb.(Phone)
	if ok {
		phone.Call()
	}
	usb.Stop()
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值